JVM是java发布服务的一个基本的配置,它管理着tomcat的内存分配及java垃圾回收机制
jvm的内存分布主要包括堆和栈,堆主要是存放new相关的对象,栈主要是存储方法、静态类、变量、数组等,
jvm内存分布示意图如下
内存的关系如下:
jdk1.7以前: 堆内存=年轻代(eden+from survivor+to survivor)+老年代(paroldgen)+永久代(perm)
jdk1.8以后: 堆内存=年轻代(eden+from survivor+to survivor)+老年代(paroldgen)
其中元空间metaspace不在虚拟内存中,而在本地内存中
如下面配置为一个tomcat的参数配置:
-Xms8g -Xmx8g -Xmn6g -XX:SurvivorRatio=4 -XX:+UseParallelOldGC -XX:+DisableExplicitGC -XX:+UseParallelGC -XX:PermSize=128m -XX:MaxPermSize=256m -XX:ParallelGCThreads=8
假设系统内存大概20g,其中该项目设置的JVM最大使用内存-Xmx8g -Xms最小使用内存8g,这里设置内存不能扩展,为了避免垃圾回收后jvm重新分配。
-Xmn6g:设置年轻代大小为6g,所以老年代大小2g。
持久代 -XX:MaxPermSize:大小设置为512m,永久代其实就是方法区,jdk8之后 永久代PermSize被废弃,使用Metaspace替代
-XX:SurvivorRatio=2 :这是年轻代中eden与survivor大小比为2:1
-XX:+DisableExplicitGC :禁止代码中显示调用GC,
-XX:+UseParallelGC: 选择年轻代垃圾回收器为并行收集器,
-XX:ParallelGCThreads=4 :当设置-XX:+UseParallelGC,垃圾回收器并行处理线程数为4,不设置默认为cpu核数,
-XX:+UseParallelOldGC :配置年老代垃圾回收集方式为并行收集。
其中,
-Xmx减去-Xmn为老年代的大小
-XX:SurvivorRatio=6 ,设置的是Eden区与每一个Survivor区的比值,可以反推出其他两个区的比值,
Eden为6, 两个Survivor(From幸存区或To幸存区)分别为1,
Eden占新生代的比例为:6/(6+1+1),
每个Survivor占1/8,两个共占2/8
根据SurvivorRatio可得计算公式:假设年轻代的空间为s,-XX:SurvivorRatio=r
eden = (r*s)/(r+1+1) from = s/(r+1+1) to = s/(r+1+1)
jvm除了设置上面的内存大小,还可以设置记录日志和执行脚本
发生堆溢出时异常文件路径:
-XX:HeapDumpPath=d:\logs\jvm.dump
发生堆溢出时候执行的脚本:
-XX:OnOutOfMemoryError=d:\run.bat
这两个操作在实际中都比较有用,比如我们的服务经常堆溢出,需要人为重启,有了这个就可以自动触发重启了,避免了服务挂了,重启不及时的情况
关于jvm的配置,可以找相关的jvm手册,目前我还没找到官网发布的手册,jvm的配置需要有丰富的经验,不可以随意配置