零 前述
本文以 G1 作为主视角来做对策分析。
jdk8 中将 GC 调整为 G1 -XX:+UseG1GC
一 从编码层面来说
1 减少对象的创建频率
尽量复用以前存在的对象,减少对象创建,那么就能减少 gc 的频率。
方法有:
单例模式
享元模式
静态对象
枚举类
对象池技术
用 StringBuilder 和 IntegerCache 等方法去代替直接创建对象
2 从根本上减少堆内存的使用
使用其它内存方式代替堆内存。当一个对象的使用生命周期被囊括在栈的生命周期内,此时 jvm 会通过逃逸分析判断该对象不需要在堆上分配内存,只需要创建在栈内存中就可以了。
栈内存是没有 gc 的,等栈的生命周期结束就被全部删除了
注意设置好 jvm 栈内存的大小,不要 OOM
也可以使用 Unsafe 去操作元空间的内存,但是要注意控制手动释放
涉及参数设置:
设置栈内存的大小,单位 kb -Xss:1024 开启逃逸分析,默认就是开启的 -XX:+DoEscapeAnalysis
3 小对象代替大对象
小对象对于 jvm 来说,是会直接创建在 eden 区的,但是大对象则会直接被分配在老年代。老年代比 eden 大很多,gc 起来更加费力。
默认情况下,只要 eden 区有足够的连续空间,不论多大的对象都会分配在 eden 区,这会导致 eden 区可能在短期内存在内存“碎片”,所以可以设置好 jvm 对大对象定义的阈值
尽量拆分大对象