searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

记一次生产容器环境Java应用内存OOM分析过程

2024-07-01 03:26:47
3
0

一、背景

生产环境某应用运行在容器集群中,此模块pod在配置2个实例,每个pod规格为4c8G。查看异常日志如下:

[o.a.http.impl.nio.client.InternalHttpAsyncClient] [] >>> I/O reactor terminated abnormally
org.apache.http.nio.reactor.IOReactorException: I/O dispatch worker terminated abnormally
	at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:359)
	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.execute(PoolingNHttpClientConnectionManager.java:221)
	at org.apache.http.impl.nio.client.CloseableHttpAsyncClientBase$1.run(CloseableHttpAsyncClientBase.java:64)
	at java.lang.Thread.run(Thread.java:750)
Caused by: java.lang.OutOfMemoryError: Java heap space
	at org.apache.http.util.ByteArrayBuffer.expand(ByteArrayBuffer.java:57)
	at org.apache.http.util.ByteArrayBuffer.append(ByteArrayBuffer.java:87)
	at org.apache.http.util.EntityUtils.toByteArray(EntityUtils.java:139)

 

一旦 IO worker异常退出,会导致后续的请求无法进行,HTTP CLIENT IO线程退出。

 

二、排查步骤

按理说查询代理模块工作任务并不繁重,主要承担查询转发逻辑,理论上8G内存应该不出问题,固问题应该在8G内存无法使用导致。通过ps -ef 查看运行命令如下:

java -server -jar app-xxxx.jar

 

为指定JDK的启动内存配置,由于使用的是JDK8,查询官方文档显示,在不指定情况下,JDK通过操作系统&内存的大小动态计算得到最大可使用的内存:

https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/parallel.html#default_heap_size

 

通过在容器内执行  java -XX:+PrintFlagsFinal -version | grep MaxHeapSize 得到:

 

即 2147483648 bytes = 2G,可以知道,在不声明内存情况下,此容器规格(8G)默认只能使用2G的heap内存。规格为8G也利用不起来,固一旦超过2G内存则会触发OOM,从而导致后续的请求异常。

三、解决办法

由于启动命令为 java -server ${JAVA_OPTS} -jar app_xxxx.jar

固环境变量中增加 JAVA_OPTS 值为 -Xms1g -Xmx7g 即可,如下图:

 

另外同时注意filecache占用的内存,在容器中filecache也认为是一种内存占用,并且可能会触发容器OOM KILL。

 

0条评论
0 / 1000
l****n
14文章数
0粉丝数
l****n
14 文章 | 0 粉丝
原创

记一次生产容器环境Java应用内存OOM分析过程

2024-07-01 03:26:47
3
0

一、背景

生产环境某应用运行在容器集群中,此模块pod在配置2个实例,每个pod规格为4c8G。查看异常日志如下:

[o.a.http.impl.nio.client.InternalHttpAsyncClient] [] >>> I/O reactor terminated abnormally
org.apache.http.nio.reactor.IOReactorException: I/O dispatch worker terminated abnormally
	at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:359)
	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.execute(PoolingNHttpClientConnectionManager.java:221)
	at org.apache.http.impl.nio.client.CloseableHttpAsyncClientBase$1.run(CloseableHttpAsyncClientBase.java:64)
	at java.lang.Thread.run(Thread.java:750)
Caused by: java.lang.OutOfMemoryError: Java heap space
	at org.apache.http.util.ByteArrayBuffer.expand(ByteArrayBuffer.java:57)
	at org.apache.http.util.ByteArrayBuffer.append(ByteArrayBuffer.java:87)
	at org.apache.http.util.EntityUtils.toByteArray(EntityUtils.java:139)

 

一旦 IO worker异常退出,会导致后续的请求无法进行,HTTP CLIENT IO线程退出。

 

二、排查步骤

按理说查询代理模块工作任务并不繁重,主要承担查询转发逻辑,理论上8G内存应该不出问题,固问题应该在8G内存无法使用导致。通过ps -ef 查看运行命令如下:

java -server -jar app-xxxx.jar

 

为指定JDK的启动内存配置,由于使用的是JDK8,查询官方文档显示,在不指定情况下,JDK通过操作系统&内存的大小动态计算得到最大可使用的内存:

https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/parallel.html#default_heap_size

 

通过在容器内执行  java -XX:+PrintFlagsFinal -version | grep MaxHeapSize 得到:

 

即 2147483648 bytes = 2G,可以知道,在不声明内存情况下,此容器规格(8G)默认只能使用2G的heap内存。规格为8G也利用不起来,固一旦超过2G内存则会触发OOM,从而导致后续的请求异常。

三、解决办法

由于启动命令为 java -server ${JAVA_OPTS} -jar app_xxxx.jar

固环境变量中增加 JAVA_OPTS 值为 -Xms1g -Xmx7g 即可,如下图:

 

另外同时注意filecache占用的内存,在容器中filecache也认为是一种内存占用,并且可能会触发容器OOM KILL。

 

文章来自个人专栏
数据库原理
14 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0