1. 对象复用与池化
-
线程局部变量:通过
ThreadLocal缓存线程私有对象,避免竞争。 -
可变对象:优先使用可修改对象(如
StringBuilder代替String拼接)。
2. 减少对象创建
-
避免隐式装箱:使用基本类型(
int而非Integer)。 -
优化循环:避免在循环内创建临时对象。
-
静态不可变对象:将常量声明为
static final(如配置参数)。
3. 数据结构优化
-
预分配容量:初始化集合时指定合理大小(如
ArrayList、HashMap)。 - 及时清理引用:移除不再使用的集合条目(避免内存泄漏)。
-
基本类型集合库:使用
Trove、Eclipse Collections避免包装类开销。
4. 内存泄漏防护
-
内部类引用:避免非静态内部类隐式持有外部类引用(尤其在异步场景)。
-
弱引用缓存:使用
WeakHashMap或SoftReference实现缓存自动清理。 -
监听器与缓存:及时移除无用的监听器或缓存条目。
5. 大对象与堆外内存
-
大对象分离:将大数组、文件流等与高频创建对象隔离,避免进入老年代。
-
堆外内存:通过
ByteBuffer.allocateDirect()或Unsafe分配内存,减少堆压力(需手动管理)。
6. GC算法与JVM调优
-
选择合适的GC:
-
G1:适用于大堆(>4GB)和低延迟需求。
-
ZGC/Shenandoah:超大堆(TB级)和极低暂停。
-
-
参数调优:
-
-Xms和-Xmx设为相同值,避免堆动态调整。 -
调整新生代比例(
-XX:NewRatio=2,老年代是新生代的2倍)。
-
7. 其他关键实践
-
避免Finalize:改用
Cleaner或PhantomReference管理资源释放。 -
字符串处理:
-
使用
String.intern()谨慎处理重复字符串(可能引起PermGen问题)。 -
优先使用
char[]而非String处理敏感数据(减少内存驻留)。
-
-
并发优化:减少锁竞争,缩短对象生命周期。
8. 监控与分析工具
-
GC日志:启用
-XX:+PrintGCDetails分析停顿原因。 -
堆分析:使用MAT、VisualVM或JProfiler定位内存泄漏。
-
压测工具:通过JMH模拟高负载场景验证优化效果。
总结
减少GC的核心在于降低对象分配速率和缩短对象生命周期。需结合业务场景权衡优化策略(如池化可能增加内存占用)。对于延迟敏感系统,建议选择低延迟GC(如ZGC)并配合代码级优化。
587

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



