阅读量:27
选择合适的垃圾回收器
根据应用场景选择匹配的GC器是优化基础。G1GC(-XX:+UseG1GC)适用于大内存(≥6GB)、对延迟有一定要求的场景(如微服务、电商系统),通过划分Region实现可预测停顿;ZGC(-XX:+UseZGC)针对超低延迟设计(目标≤10ms),适合实时数据分析、高频交易系统;Parallel GC(-XX:+UseParallelGC+-XX:+UseParallelOldGC)以高吞吐量为目标,适合后台批处理、科学计算等能容忍较长停顿的场景;CMS(-XX:+UseConcMarkSweepGC)曾用于Web服务器等响应时间敏感场景,但已逐渐被G1/ZGC取代。
合理配置堆内存与分代比例
- 堆内存大小:通过
-Xms(初始堆)和-Xmx(最大堆)设置相同值(如-Xms8g -Xmx8g),避免运行时动态调整带来的性能损耗; - 年轻代与老年代比例:用
-XX:NewRatio调整(如-XX:NewRatio=3表示年轻代占1/4,老年代占3/4),年轻代过大易导致频繁Minor GC,过小则增加Full GC概率; - Eden与Survivor区比例:通过
-XX:SurvivorRatio设置(如-XX:SurvivorRatio=8表示Eden区占80%,每个Survivor区占10%),控制对象从Eden晋升到老年代的阈值(-XX:MaxTenuringThreshold,默认15,可根据对象存活周期调整)。
优化GC线程数量
- 并行GC线程:
-XX:ParallelGCThreads设置并行收集的线程数,建议等于CPU核心数(如8核设置为8),充分利用多核提升GC效率; - 并发GC线程:
-XX:ConcGCThreads设置并发标记阶段的线程数,通常为并行线程数的1/4(如-XX:ConcGCThreads=2),避免过多线程抢占应用资源。
调整GC停顿时间目标
对于延迟敏感应用,通过-XX:MaxGCPauseMillis设定期望的最大停顿时间(如-XX:MaxGCPauseMillis=200表示允许200ms停顿),GC器会自动调整堆大小和回收策略以接近该目标(如G1会根据此值动态选择回收的Region数量)。
监控GC行为与分析日志
- 开启GC日志:添加
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/var/log/gc.log参数,记录GC时间、类型(Minor/Full GC)、回收前后堆大小等信息; - 使用监控工具:通过
jstat -gcutil实时查看GC次数、停顿时间占比;用1000 VisualVM、Java Mission Control分析GC日志,识别频繁Full GC、停顿过长等问题; - 生成堆转储:当出现内存泄漏时,用
jmap -dump:live,format=b,file=heapdump.hprof生成堆转储文件,通过MAT、YourKit等工具分析内存占用情况。
代码层面减少GC压力
- 对象重用:避免在循环中创建临时对象(如用
StringBuilder替代+拼接字符串),使用对象池(如Apache Commons Pool)复用昂贵对象; - 选择合适数据结构:根据场景选择内存占用少、操作高效的结构(如
ArrayList替代LinkedList(随机访问多)、HashMap替代TreeMap(无序场景)); - 控制对象生命周期:及时释放无用对象引用(如将集合置为
null),避免内存泄漏;减少长生命周期对象持有短生命周期对象(如静态集合中存储临时对象)。
系统级优化辅助
- 调整内核参数:修改
/etc/sysctl.conf,增加vm.swappiness(如设为10,降低系统使用swap的倾向)、net.core.somaxconn(如设为65535,提升网络连接能力);通过ulimit -n 65535增加文件描述符限制,适应高并发场景; - 清理系统缓存:定期执行
sync; echo 3 > /proc/sys/vm/drop_caches清理pagecache、slab等缓存,释放内存供Java应用使用。