(未完结)JAVA7 JVM调优 测试环境
先说明下这里是测试环境实验,并且JVM调优要根据项目和运行实际情况来进行调整,极端情况不可按部就班
测试环境如下:1个1核2线程的CPU(2个逻辑CPU),8G内存,JDK:1.7,tomcat:8.5.70,JVM参数为默认
先在 catalina.sh 中添加参数打印GC信息到日志文件
JAVA_OPTS="-XX:+PrintGCDetails -Xloggc:/opt/logs/gc.log"
优化项1
文章图片
默认情况堆最小空间和最大空间不一致,为了避免每次垃圾回收完成后JVM重新分配内存,调整为一致,默认最小为总内存1/64,最大为1/4 通过计算有一定偏差,手动设置为最小和最大都为2G
JAVA_OPTS="-Xms2G -Xmx2G -XX:+PrintGCDetails -Xloggc:/opt/logs/gc.log"
启动后通过jstat -gc -h 10 pid 1s 查看pid jvm中各空间使用情况 1秒刷新一次 保留10行
文章图片
发现S1 大小在YOUNG GC后会发生变化,通过资料查询发现可能是自动调整功能(猜测)
文章图片
(猜测) S1使用过程中, 将上一次复制过来的数据清理后存活的大小按一定比例存放, 即:不占据过多空间。S0使用过程中, 将S1扩容至S0大小,防止S0和Eden数据复制过来再大幅度扩容
【(未完结)JAVA7 JVM调优 测试环境】我添加了-XX:SurvivorRatio=8 让S0 和 S1 同样大小 占年轻代1/10, 这样young GC 后 S0 S1容量不再发生变化,便于调试变化的值
文章图片
内存分配到这里结束了,下面就是垃圾回收器的选择,官方JDK7这方面描述的比较少,这里参考8的官方文档探索一下
垃圾回收器主要考虑在老年代的回收,因为青年代大部分不到15岁就被清除了(一次young gc 算一岁,默认15次)
CMS(Concurrent Mark Sweep) 主要用于老年代的垃圾回收, 年轻代仍适用串行或并行的方式进行垃圾回收, 相比于并行收集器,采用并发标记来减少STW时间。但同样有一定的缺点,比如老年代清除后有空间碎片,如果有一个大对象进入老年代,没有连续的空间进行过存储,将进行一次不必要的Full GC,而且在并行标记时也会占用更多的CPU。
清除步骤如下:
- 初始标记(CMS initial mark):独占CPU,stop-the-world, 仅标记GCroots能直接关联的对象,速度比较快;
- 并发标记(CMS concurrent mark):可以和用户线程并发执行,通过GCRoots Tracing 标记所有可达对象;
- 重新标记(CMS remark):独占CPU,stop-the-world, 对并发标记阶段用户线程运行产生的垃圾对象进行标记修正,以及更新逃逸对象;
- 并发清理(CMS concurrent sweep):可以和用户线程并发执行,清理在重复标记中被标记为可回收的对象。
G1(Garbage-First) 垃圾收集器是一种服务器式垃圾收集器,针对具有大内存的多处理器机器。它试图以高概率满足垃圾收集 (GC) 暂停时间目标,同时实现高吞吐量。全堆操作(例如全局标记)与应用程序线程同时执行。这可以防止与堆或实时数据大小成正比的中断。其他的垃圾回收相比, G1弱化了分代的情况, 用了Region的结构来替代新生代年老代。
资料:
JAVA7官方JVM调优白皮书
JAVA7官方JVM参数
JAVA各版本官网文档
CMS垃圾回收器
G1垃圾回收期
借鉴了大神的CMS与G1区别
推荐阅读
- 我要我们在一起(二)
- 把一切献给现在
- 年轻人对未来迷茫时该怎么办()
- 【挑战日更】Day6.《终身学习.10个你必须掌握的未来生存法则》摘录之三
- 未来丛林历险记
- 未来不可期,但愿你无悔
- 父母链接八~未了情结
- 阅读《此生未完成》一
- 秋已动夏未走
- 再见,L