前言
JVM 的内存优化其实就是对新生代、老年代的配置进行调优,那么应该设置多大呢,这是没有一定的答案的,调优就是一个找答案的过程,一边优化一边测试找到满意的答案,物理内存一定的情况下,新生代设置越大,老年代就越小,Full GC 频率就越高,但 Full GC 时间越短;相反新生代设置越小,老年代就越大,Full GC 频率就越低,但每次 Full GC 消耗的时间越大。
建议
个人建议如下:
堆优化
- 把堆的参数 -Xms 和 -Xmx 的值设置成相等的,堆大小默认为 -Xms 指定的大小,默认空闲堆内存小于 40% 时,JVM 会扩大堆到 -Xmx 指定的大小;空闲堆内存大于 70% 时,JVM 会减小堆到 -Xms 指定的大小。如果在 Full GC 后满足不了内存需求会动态调整,这个时候比较耗费资源。
- 尽量新生代设置大一些,让对象在新生代存活时间长一点,每次 Minor GC 都要尽可能多的收集垃圾对象,防止或延迟对象进入老年代的机会,以减少应用程序发生 Full GC 的频率。
- 老年代如果使用 CMS 收集器,新生代可以不用太大,因为 CMS 的并行收集速度也很快,收集过程比较耗时的并发标记和并发清除阶段都可以与用户线程并发执行。
代码优化
有时出现内存泄漏的问题除了 JVM 配置存在问题,也有可能是代码的问题,所以如下建议:
- 避免创建过大的对象或数组:过大的对象或数组在新生代没有足够大的空间容纳时,会直接进入老年代,如果是存活时间短的大对象,会提前触发 Full GC。
- 避免同时加载大量数据,如一次从数据库中取出大量数据,或者一次从 Excel 中读取大量记录,可以分批读取,用完尽快清空引用。
- 当集合中有对象的引用,这些对象使用完之后要尽快把集合中的引用清空,这些无用对象尽快回收避免进入老年代。
- 可以在合适的场景(如实现缓存)采用软引用、弱引用,比如用软引用来为 student 分配实例:SoftReference student =new SoftReference(); 在发生内存溢出前,会将 student 列入回收范围进行二次回收,如果这次回收还没有足够内存,才会抛出内存溢出的异常。
下面是常用 JVM 参数可以参考,可以根据参数进行调整优化:

本文探讨了JVM内存优化的关键,强调了新生代与老年代配置的重要性,指出堆大小设置对FullGC频率和时间的影响。建议设置-Xms和-Xmx相等以稳定堆大小,并优化代码以避免大对象创建、一次性加载大量数据和未及时释放集合引用导致的内存问题。推荐使用CMS收集器并利用软引用、弱引用进行缓存管理。同时提供了常用的JVM调优参数。

397

被折叠的 条评论
为什么被折叠?



