赵志浩
Published on 2019-11-24 / 23 Visits
1
0

常见的 由于未调整Linux ulimit 而引起的内存溢出问题

本篇共引出三个问题:

1、ulimit 的调整(否则将默认进程只能创建1024个线程)

2、XSS配置的说明(默认线程为1M,此处配置XSS线程所占用内存为246K)

3、 线程所占用的内存为堆外内存(相比大家也都知晓该问题,本篇也是因为服务内存不足,调整Ulimit后还是存在oom的问题,而最终引起并说明下该线程堆外的问题)

 

 注意:java中每实例化一个线程,则是向操作系统服务器请求实例化一个本地内存,并非是直接使用的JVM中所配置的堆的内存的大小,需知晓

在直接使用线上内存分析时,曾出现类似的一个问题是这样的,

线上服务器共8G内存,通过 ps -ef|grep java,可以查看共部署了3台服务,

前两台robot服务,分别配置Xms为2G,我们的core设置JVM参数为-Xms为3G,

此时则已经吃掉了7G的内存,除去服务器自身再吃掉500M内存,那么此时可供使用的内存仅有500M左右。

而此时服务器频繁报错异常则为不能够创建新的本地线程,最初时怀疑是 linux 服务器所设置的进程可开启线程数较少的原因,查看ulimit -a 发现,服务器的确没有被优化过,默认ulimit -u的参数值为1024,即的确没有调整过linux服务器的最大线程创建数的值。

      此时通过linux -u调整参数为 10240,在已有的可创建线程数量上乘以10,需要提及一下(此时的,JVM针对单个线程的堆栈占用内存此时配置的是246K,线程所设置的占用内存较小,则可以保证所创建的线程的数量越多,这是ok的)

      此时在设置了ulimit参数后,过了一天,重复出现了,本地线程创建失败,内存异常的提示,此时则确认原因为:java线程在实例化创建时,是向服务器操作系统申请内存进行线程的创建,并非是使用的JVM所配置的堆的内存空间进行创建,所以此时问题已经可以很明显了,服务器基本还剩余的500M内存,是不够线程的创建数量的,并且是部署了三个项目的情况下,分别开了三个容器Jetty。

      三个项目同时运行,所开启的线程数,必然是500M内存,所不够的,所以此时的解决方式则是:

1、申请增加服务器内存

2、重新调整三个容器中JVM的配置参数

即调小JVM的堆的内存配置,剩余出较多的服务器内存,用于创建线程时使用,调整了-Xms和-Xmx的堆内存配置。

当然,既然已经调整了Xmx堆的内存配置,则同步也调整了年轻代,Xmn的配置,此处我们的配置比例基本为3:1,即堆内存和年轻代的设置比例。

 

原创声明:作者:赵志浩、个人博客地址:https://zhaozhihao.com

原创声明:笔名:陈咬金、 博客园地址:https://www.cnblogs.com/zh94/


Comment