OOM之JVM调优(Tomcat配置OutOfMemoryError之Out of swap space报错)

遇到一个JVM奔溃问题,JVM运行一些不定时时间后奔溃,查看了一下报错日志

如下:
在这里插入图片描述
关键词汇:OutOfMemoryError,growableArray.cpp,Out of swap space

growableArray.cpp文件存在一个bug,在堆比较大的情况下会导致JVM奔溃
原文链接:https://blog.csdn.net/weixin_33728708/article/details/92619121
jdk 6 版本update 到 14可以解决。

但考虑到当前服务器搭载的旧项目还在跑,换完后可能会出现影响项目问题,所以改用“增加内存配置”的方法先试一试。

Tomcat配置内存的方法:
在tomcat主目录 bin文件夹 下修改catalina.bat
在第二行添加如下代码:
set JAVA_OPTS=%JAVA_OPTS% -server -Xms1236m -Xmx1236m -XX:MaxNewSize=512m -XX:PermSize=1236m -XX:MaxPermSize=1236m
在这里插入图片描述
JVM存储数据的内容的内存分为
1.堆区Heap space(Java堆:所有的线程共享该区域):通过new的方式创建的对象(一个类的实例)、数组所占的空间。
注意:
配置堆区的参数:-Xms、-Xmx、-XX:newSize、-XX:MaxnewSize、-Xmn
1) 堆区还细分为新生代(Eden空间、From Survivor空间、To Survivor空间)、老生代(Tenured Generation空间)。
Java Heap分为3个区,Young即新生代,Old即老生代和Permanent。Young保存刚实例化的对象。当该区被填满时,GC会将对象移到Old区。Permanent区则负责保存反射对象。
Heap= young + old = (eden + from + to) + (old + permanent)
Eden: (from + to) = SurvivorRatio = 8(默认) Eden= 8/(8+1+1) from=1/(8+1+1)=to
Young:old = 1:2(默认)= NewRatio =2
2)Java垃圾回收机制只作用于堆区,对非堆区没有作用。

2.非堆区PermGen space:代码、常量、外部访问(比如流在传输数据时所占用的资源)等。
配置非堆区的参数:-XX:PermSize、-XX:MaxPermSize
原文链接:https://blog.csdn.net/tree_ifconfig/article/details/81222196

参数介绍:
-xms:java虚拟机堆区内存初始内存分配的大小
-xmx:Java虚拟机堆区内存可被分配的最大上限。偏小会OutOfMemory,且无法被try catch捕获
-xmn: 设置Yong Generation的初始值大小,和Newsize意思一样,哪个在后面就以哪个为主
-Newsize : 设置Yong Generation的初始值大小
-Maxnewsize:设置Yong Generation的最大值大小
-xss: 设置每个线程的堆栈大小,JDK5以后默认1M,之前默认256K,调小会生成更多线程数,但也不能超过3000~5000

-maxnewsize:新生代可被分配的内存的最大上限(该值需要小于-Xmx的值)。
-permsize:非堆区初始化内存分配大小
-maxpermsize:非堆区初始化内存最大上限
在程序中通过new关键字新建出来的对象,一般都会分配在新生代中。当新生代满了后,JVM会通过GC来进行一次小规模的垃圾回收,此时新生代中存活的对象会被移动至老生代

参数意义:
PermSize和MaxPermSize指明虚拟机为java永久生成对象(Permanate generation)–永久代。永久保存的区域,用于存放Class和Meta信息,Class在被Load的时候被放入该区域,GC(Garbage Collection)应该不会对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。
xms/xmx:定义YOUNG+OLD段的总尺寸,ms为JVM启动时YOUNG+OLD的内存大小;mx为最大可占用的YOUNG+OLD内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。
NewSize/MaxNewSize:定义YOUNG段的尺寸,NewSize为JVM启动时YOUNG的内存大小;MaxNewSize为最大可占用的YOUNG内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。
PermSize/MaxPermSize:定义Perm段的尺寸,PermSize为JVM启动时Perm的内存大小;MaxPermSize为最大可占用的Perm内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。
SurvivorRatio:设置YOUNG代中Survivor空间和Eden空间的比例,记得加上配置-XX:-UseAdaptiveSizePolicy,否则还是默认的8.

申请一块内存的过程:
A. JVM会试图为相关Java对象在Eden中初始化一块内存区域
B. 当Eden空间足够时,内存申请结束。否则到下一步
C. JVM试图释放在Eden中所有不活跃的对象(这属于1或更高级的垃圾回收);释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区/OLD区
D. Survivor区被用来作为Eden及OLD的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区
E. 当OLD区空间不够时,JVM会在OLD区进行完全的垃圾收集(0级)
F. 完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”out of memory错误
原文链接:https://www.ytexpress.cn/love/412102.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值