问题描述:
我们公司产品线上运行过程中,需要调用第三方Web Service进行数据抓取,现场小伙伴反馈,调用第三方接口,导致第三方程序内存溢出,具体报错信息:
OutOfMemoryError: Java heap space
现场第三方通过调整内存大小为4G,仍然报错,至此寻求帮助。
原因分析:
关于内存溢出
Tomcat本身是依赖于JVM虚拟机的,报错问题的解决还是回归到JVM对内存的管理上。
JVM虚拟机内存管理分为:堆内存(运行时数据区域)、非堆内存(JVM本身使用的内存)
常见内存溢出报错信息
- OutOfMemoryError: Java heap space 堆溢出
- OutOfMemoryError: PermGen space 非堆溢出
- OutOfMemoryError: unable to create new native thread. 无法创建新的线程,并不常见
配置解决方案
-Xmx Java Heap最大值,默认值为物理内存的1/4;
-Xms Java Heap初始值,默认是物理内存的1/64;
-Xmn 设置JVM堆的‘新生代’的最大内存;
-Xss 每个线程的Stack大小;
-XX:PermSize:设定内存的永久保存区域;
-XX:MaxPermSize:设定最大内存的永久保存区域;
-XX:NewSize:设置JVM堆的‘新生代’的默认大小;
-XX:MaxNewSize:设置JVM堆的‘新生代’的最大大小;
重要知识点
- 在Java中,JVM提供GC机制,由一个被称为垃圾回收器的守护线程执行的。
- GC 回收一个对象之前会调用对象的finalize()方法
- System.gc()和Runtime.gc()会向JVM发送执行GC的请求,但是JVM不保证一定会执行GC。
- 查看堆内存信息:
Runtime.getRuntime().maxMemory(); //最大可用内存,对应-Xmx
Runtime.getRuntime().freeMemory(); //当前JVM空闲内存
Runtime.getRuntime().totalMemory(); //当前JVM占用的内存总数,其值相当于当前JVM已使用的内存及freeMemory()的总和
参考博文
https://blog.csdn.net/qq_35440040/article/details/97805987
解决方案:
经过询问,现场的物理内存大小为32G,所以第三方平台设置为4G肯定不会解决问题的,Java Heap最大值,默认值为物理内存的1/4;,所以需要设置为至少8G以上才可以生效。
打开Tomcat根目录下的bin文件夹,编辑catalina.bat(linux为catalina.sh),将其中的%CATALINA_OPTS%(共有四处)替换为:-Xmx10240m -Xms10240m