压测过程中,短时间(比如20S后)Eden区就满了,此时再运行的时候对象已经无法分配,会触发,
假设在这次GC后S1装入100M,马上过20S又会触发一次,多出来的100M存活对象+S1区的100M已经无法顺利放入到S2区,此时就会触发JVM的动态年龄机制,将一批100M左右的对象推到老年代保存,持续运行一段时间,系统可能一个小时候内就会触发一次 。
按照默认8:1:1的比例来分配时, 区只有 1G的 10%左右,也就是几十到100M,
如果 每次minor GC垃圾回收过后进入对象很多,并且对象大小很快超过的 50%,那么会触发动态年龄判定规则,让部分对象进入老年代.
而一个GC过程中,可能部分WEB请求未处理完毕, 几十兆对象,进入的概率,是非常大的,甚至是一定会发生的.
如何解决这个问题呢?为了让对象尽可能的在新生代的eden区和区, 尽可能的让区内存多一点,达到200兆左右,
于是我们可以更新下JVM参数设置:
-Xms3072M -Xmx3072M -Xmn2048M -Xss1M -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M-XX:SurvivorRatio=8说明:‐Xmn2048M ‐XX:SurvivorRatio=8 年轻代大小2g,eden与survivor的比例为8:1:1,也就是1.6g:0.2g:0.2g
达到200m,如果几十兆对象到底,也不一定超过 50%
这样可以防止每次垃圾回收过后,对象太早超过 50% ,
这样就降低了因为对象动态年龄判断原则导致的对象频繁进入老年代的问题,
什么是JVM动态年龄判断规则呢?
对象进入老年代的动态年龄判断规则(动态晋升年龄计算阈值):Minor GC 时,中年龄 1 到 N 的对象大小超过的 50% 时,则将大于等于年龄 N 的对象放入老年代 。
核心的优化策略是:是让短期存活的对象尽量都留在里,不要进入老年代,这样在minor gc的时候这些对象都会被回收,不会进到老年代从而导致full gc 。
应该如何去评估新生代内存和分配合适?
这里特别说一下,JVM最重要最核心的参数是去评估内存和分配,
第一步需要指定堆内存的大小,这个是系统上线必须要做的,-Xms 初始堆大小,-Xmx 最大堆大小,
后台Java服务中一般都指定为系统内存的一半,过大会佔用服务器的系统资源,过小则无法发挥JVM的最佳性能 。
其次需要指定-Xmn新生代的大小,这个参数非常关键,灵活度很大,虽然sun官方推荐为3/8大小,但是要根据业务场景来定:
服务有状态,则意味著会有更多的本地缓存和会话状态信息常驻内存,应为要给老年代设置更大的空间来存放这些对象 。
step4:栈内存大小多少比较合适?
-Xss栈内存大小,设置单个线程栈大小,默认值和JDK版本、系统有关,一般默认512~ 。一个后台服务如果常驻线程有几百个,那麽栈内存这边也会佔用了几百M的大小 。
step5:对象年龄应该为多少才移动到老年代比较合适?
假设一次minor gc要间隔二三十秒,并且,大多数对象一般在几秒内就会变为垃圾,
如果对象这么长时间都没被回收,比如2分钟没有回收,可以认为这些对象是会存活的比较长的对象,从而移动到老年代,而不是继续一直占用区空间 。
所以,可以将默认的15岁改小一点,比如改为5,
那么意味着对象要经过5次minor gc才会进入老年代,整个时间也有一两分钟了(5*30s= 150s),和几秒的时间相比,对象已经存活了足够长时间了 。
所以:可以适当调整JVM参数如下:
‐Xms3072M ‐Xmx3072M ‐Xmn2048M ‐Xss1M ‐XX:MetaspaceSize=256M ‐XX:MaxMetaspaceSize=256M ‐XX:SurvivorRatio=8 ‐XX:MaxTenuringThreshold=5
- cocos ceater 如何实现显示 Tip 的 同时能响应点击其他功能?
- 如何理解孺子可教也的意思 孺子可教也的意思是啥啊
- 如何利用RecyclerView打造炫酷滑动卡片
- Excel甘特图如何修改
- 照片无法在photos显示_如何使用Google Photos轻松进行照片修复
- 什么是信息孤岛?如何打破信息孤岛?
- 如何在一周内成为更好的软件测试员?七个步骤带你一步一步晋升...
- 如何提高苹果着色
- 微信商家收款码如何申请
- 如何关闭微信小盾牌