JVM参数调优学习笔记

JVM参数调优

一.OS不同情况的设置

一般情况下,64位的OS性能比32位的好。但是根据Sun官方说明,32位的JVM反而比64位的JVM性能要好。这里并不是建议大家使用32位JVM,只是说可以在64位OS系统环境下,调优效果不大可以尝试换成32位的JVM。

具体启动命令加入-d32,可以启用32位JVM(如果可用的话):

java -d32 -jar jarfile [args...]

二.JVM内存模型及参数调优

JVM内存并不是设置越大越好。太大会造成寻址计算和垃圾回收开销过大,太小资源又不够用。先讲一下JVM每个区的作用。

在这里插入图片描述

可以从上图看到,JVM内存结构大分类上可以分为Non-Heap和Heap。

1.Non-Heap

官方定义:

Non-heap memory includes a method area shared among all threads and memory required for the internal processing or optimization for the Java VM.

简单翻译:Non-heap(非堆区)主要是由被线程共享的方法区和Java虚拟机内部进程所需内存组成。

具体说明:

name说明相关JVM参数回收情况
CodeCache代码缓冲区,用于JIT编译和保存本地代码(Native code)所需的内存。-XX:ReservedCodeCacheSize
java7默认值48M,java8默认值250M。
默认值已经够用,一般不会去修改。出现下列情况,可以根据情况修改这个参数值:
1.出现Hotspot编译失败。(增加)
2.为了减少JVM内存。(减少)
不回收
Permanent Generation space持久代。主要存放类加载信息、类结构信息、类常量、类方法等等。Java1.7:
-XX:PermSize
-XX:MaxPermSize 默认值64M
一般来说默认的PermSize已经够用,但是如果应用里用到了很多动态加载,那可能就需要根据需要调整一下MaxPermSize大小
Java1.8:
-XX:MetaspaceSize 默认值:20m
-XX:MaxMetaspaceSize 默认值:机器最大内存
FullGC时回收
Direct Memory暂定为持久代一部分。使用java.nio.ByteBuffer类的allocateDirect方法分配的内存,NIO基本上都是采用这个区域来交互数据。-XX:MaxDirectMemorySize
默认值为最大可用堆空间。当调用allocateDirect方法时,都会先去判断是否达到最大堆内存,如果达到则先调用System.gc()清理内存。对于采取NIO的应用,建议手动设置-XX:MaxDirectMemorySize的大小,避免内存浪费。
FullGC时回收

2.Heap

官方定义:

Heap memory is the runtime data area from which the Java VM allocates memory for all class instances and arrays.The heap may be of a fixed or variable size. The garbage collector is an automatic memory management system that reclaims heap memory for objects.

堆区的基本管理过程:

创建的新对象开始放在Eden区,在MInor GC后剩余对象放入Survivor区(To Survivor或者From Survivor区**<因为采用的复制算法>**,如果Survivor区容量不够,直接放入Tenured区),在经过多次Minor GC后依然存活的对象放入Tenured区。等Tenued区容量不够时,就会触发Full GC。

对于堆区的参数调优,主要是:合理调整新生代和老年代的大小,让对象尽量在新生代就被Minor GC回收掉,减少Full GC的次数,Full GC的时候会发生"stop the world”。

JVM调优参数:

参数说明调优建议
-XmsHeap Size最小值1.最好设置为应用正常时消耗的内存大小。
2.Java Performance推荐大小:
Xmx 和 Xms设置为老年代存活对象的3-4倍,即FullGC之后的老年代内存占用的3-4倍
3.原因:
过大:增加GC时间,浪费内存。
过小:JVM性能浪费在申请内存上。
-XmxHeap Size最大值1.设置为应用最大峰值时所消耗的内存。
2.Java Performance推荐大小:
Xmx 和 Xms设置为老年代存活对象的3-4倍,即FullGC之后的老年代内存占用的3-4倍
3.原因:
太大浪费内存,计算寻址过大降低性能。
-XmnYoungGen大小1.Xmn=1/3Xmx
2.Java Performance推荐大小:
Xmn设置为老年代存活对象的1-1.5倍。
3.原因:
过大:导致Minor GC时间过长。
过小:频繁导致拷贝到老年代,影响性能。
具体可以根据应用的特点来进行设置,如果缓存数据多,新建对象少的话可以稍微小一点。如果每次请求都会创建较多对象,就要稍微设置大一点。
-XX:NewSize新生代初始值
-XX:MaxNewSize新生代最大值-XX:NewSize和-XX:MaxNewSize这两个设置相对于-Xmn来说要灵活一点,对于需要新生代时大时小的情况,这种配置一个范围由于-Xmn。
-XX:SurvivorRatio新生代中Eden区和两个Survivor区的比值注意Survivor区是两个,也就是说SurvivorRatio=3的话,实际上是Eden:to Survivor:from Survivor=3:1:1。默认为8。
tips:ParallelScavenge系的GC最初设计默认打开AdaptiveSizePolicy的,它会自动、自适应的调整各种参数。JVM参数中不显式设置而采用默认值并且UseAdaptiveSizePolicy不关掉的话,可能造成比例不为默认值。

三.垃圾收集器选择

JVM提供了三种垃圾收集器:

垃圾收集器说明
串行收集器-XX:+UseSerialGC
串行收集使用单线程处理所有垃圾回收工作,实现容易,效率比较高。但是无法使用多处理器的优势,所以此收集适合单处理器机器。当然,此收集器也可以用在小数据量(100M 左右)情况下的多处理器机器上。
并行收集器新生代:-XX:+UseParallelGC 老年代:-XX:+UseParallelOldGC 线程数:-XX:ParallelGCThreads
最大垃圾回收暂停时间:-XX:MaxGCPauseMillis,如果设置了这个参数,堆大小和垃圾回收相关参数会进行调整以达到指定值。可能会减少应用的吞吐量。
吞吐量:-XX:GCTimeRatio,公式为 1/(1+N)。例如,-XX:GCTimeRatio=19 时,表示 5%的时间用于垃圾回收。默认情况为 99,即 1%的时间用于垃圾回收。
并发收集器-XX:+UseConcMarkSweepGC
可能出现的问题:
由于在垃圾回收过程中,不中止,这也意味着边回收,程序会生产新垃圾。这可能出现一个问题,垃圾还没有回收完,堆就消耗满,结果出现“Concurrent Mode Failure”错误。解决这个问题,通过“-XX:CMSInitiatingOccupancyFraction”参数来设置还有多少剩余堆空间时开始执行并发收集。

参考资料:
《深入理解Java虚拟机:JVM高级特性与最佳实践》
《Java进程JVM参数调优指导》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值