JVM GC优化核心是减少对象创建与延长存活期:复用对象(如ThreadLocal、静态常量)、避免字符串拼接、及时清理集合引用、慎用static持有、优先基本类型、善用弱引用与对象池。

核心思路很直接:让 JVM 少“干活”——不是靠调参数强行压 GC,而是从源头减少它要回收的东西。频繁 GC 本质是代码在短时间内制造了大量短命对象,堆空间被快速填满,触发回收。优化重点就是控制对象的“出生率”和“存活期”。
复用对象,别总 new
循环里、高频方法中反复创建 StringBuilder、ArrayList、DateFormatter、临时字符串等,是最常见的“GC 加速器”。这些对象一用完就变成垃圾,Eden 区很快撑爆。
- 用 ThreadLocal 管理线程内可复用对象,比如 StringBuilder 或 JSON 解析器实例
- 把方法内创建的对象提到类成员或静态常量(前提是线程安全或无状态)
- 避免字符串拼接写成
"a" + "b" + obj.toString(),改用 StringBuilder 或 String.format(内部也复用)
管好对象生命周期
对象不该活的时候还挂着引用,就会拖慢回收节奏,甚至被错误晋升到老年代,引发更重的 Full GC。
- 集合类使用完及时 clear(),而不是等着被 GC;尤其注意缓存、监听器、回调注册表这类长生命周期容器
- 不用的对象显式赋 null(对大对象或长生命周期引用有效,比如 Activity 中的 Bitmap、大型 List)
- 慎用 static 持有 Activity、Context、View 等,容易造成内存泄漏,让一堆本该回收的对象卡在老年代
用对数据结构和类型
有些写法看着简洁,背后却悄悄生成一堆中间对象。
- 基本类型优先用 int/long/double,少用 Integer/Long/Double;自动装箱拆箱会在堆上创建包装类对象
- 遍历集合时用增强 for 或 Iterator,避免通过 get(i) 频繁访问 ArrayList —— 虽然不直接产垃圾,但配合不当容易诱发冗余对象(如每次取值都 new 一个 DTO)
- 大数组或大对象尽量延迟初始化,或考虑分块处理,避免一次性占满 Eden 区导致 Minor GC 提前触发
善用弱引用与对象池
对必须频繁创建又需一定状态的对象(如网络连接、解析器、图形上下文),靠手动复用太难管,得靠机制兜底。
- 缓存场景下,用 WeakReference 或 SoftReference 包裹 value,让 GC 在内存紧张时能主动清理
- 高并发、固定模式的对象(如日志事件、消息体),可用轻量级对象池(如 Apache Commons Pool 或自定义 Stack 池),get → use → return,避免重复构造
- 注意:对象池不是万能药,池大小不合理反而增加管理开销,优先用于构造成本高、复用率高的对象

















