航母指挥官2免安装绿色中文版
1.21G · 2025-09-11
文章内容收录到个人网站,方便阅读:hardyfish.top/
现象分析
监控 JVM GC 情况
通过 JVM 选项打开 GC 日志
可以通过 GC 日志 观察 GC 频率:
# JDK 8
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log
# JDK 9+
-Xlog:gc*:file=gc.log:time,uptime,level,tags
然后执行:
tail -f gc.log
示例 GC 日志:
[GC (Allocation Failure) [PSYoungGen: 256M->64M(512M)] 512M->320M(1024M), 0.015s]
PSYoungGen: 256M->64M(512M)
→ 年轻代 GC,清理后剩 64M0.015s
→ GC 耗时 15msAllocation Failure
→ 由于分配失败触发 GC✅ 如果 PSYoungGen
频繁触发,则表示年轻代回收频率过高!
通过 jstat
监控 GC
使用 jstat
观察年轻代的 分配速率 & GC 频率:
jstat -gc <pid> 1000
示例输出:
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
512.0 512.0 0.0 256.0 4096.0 1024.0 8192.0 4096.0 1024.0 512.0 512.0 256.0 14567 512.32 123 32.89 545.21
使用 VisualVM
监控 GC
VisualVM
Eden
& Survivor
区的变化✅ 如果 Eden 区持续增长,并且 YGC 次数飙升,则说明年轻代 GC 过于频繁。
使用 jmap
分析对象占用
jmap -histo:live <pid> | head -20
示例输出:
#num #instances #bytes class name
----------------------------------------------
1: 150000 9600000 [C
2: 50000 4800000 java.lang.String
3: 40000 3200000 java.util.HashMap$Node
4: 30000 2800000 java.lang.Integer
...
采样分析短生命周期对象
使用 jprofiler
或 Async-Profiler
进行对象分配分析:
# 运行 Async-Profiler 采样 30 秒
./profiler.sh -d 30 -f heap.svg <pid>
✅ 找到 GC 频繁回收的热点代码,如 List
、Map
频繁创建后立即释放。
调整 Eden 区大小
可以适当增大:
-XX:NewRatio=2 # 年轻代占堆内存的 1/3
-XX:SurvivorRatio=6 # Eden : Survivor = 6:1
✅ 减少 GC 触发频率,提高对象存活率。
预分配对象,减少短命对象
短生命周期对象会快速进入 Eden,导致频繁 GC:
// 优化前(大量创建临时对象)
for (int i = 0; i < 10000; i++) {
String s = new String("hello"); // 每次都会创建新的 String
}
✅ 优化后,使用 String Pool 或对象重用
for (int i = 0; i < 10000; i++) {
String s = "hello"; // 直接引用字符串常量池
}
使用对象池(Object Pool)
如果高频创建对象,如 Thread
、Connection
,可以使用 对象池:
// 使用线程池代替频繁创建线程
ExecutorService executor = Executors.newFixedThreadPool(10);
✅ 避免频繁创建销毁对象,降低 GC 压力。
避免 SoftReference
/WeakReference
过多
如果 SoftReference
和 WeakReference
太多,可能导致频繁 GC 回收:
SoftReference<byte[]> ref = new SoftReference<>(new byte[1024 * 1024]);
✅ 尽量避免短时间大量创建 SoftReference
,避免触发 GC。
降低 Survivor 区溢出
当 Survivor 区过小,新生代对象过快晋升到老年代,可能会导致 Full GC 过多:
-XX:SurvivorRatio=8 # Eden:Survivor = 8:1
✅ 让对象在 Survivor 区存活更久,减少老年代晋升压力。
总结
优化方向 | 方案 |
---|---|
监控 GC 频率 | -XX:+PrintGCDetails / jstat -gc <pid> |
分析对象分配 | jmap -histo / Async-Profiler |
调整 Eden 大小 | -XX:NewRatio=2 |
减少临时对象 | 使用对象池、缓存,避免 new String() |
减少 Survivor 溢出 | -XX:SurvivorRatio=8 ,减少对象晋升老年代 |
优化 SoftReference | 避免过多软引用 |
杭州萧山推出线下消费补贴:18-40 岁青年购 3C 数码产品最高可补 1000 元
努比亚张雷:手机市场从不是“非此即彼”的零和博弈,行业活力正来自这种差异化