JVM 调优常用的监控工具
JDK 自带了很多监控工具,都位于 JDK 的 bin 目录下,其中最常用的是 jconsole
和 jvisualvm
这两款视图监控工具。
jconsole:用于对 JVM 中的内存、线程和类等进行监控;
jvisualvm:JDK 自带的全能分析工具,可以分析:内存快照、线程快照、程序死锁、监控内存的变化、GC 变化等。
常用的 JVM 调优的参数
参数 | 描述 |
---|---|
-Xms2g | 初始化推大小为 2g |
-Xmx2g | 堆最大内存为 2g |
-XX:NewRatio=4 | 设置年轻的和老年代的内存比例为 1:4 |
-XX:SurvivorRatio=8 | 设置新生代 Eden 和 Survivor 比例为 8:2 |
–XX:+UseParNewGC | 指定使用 ParNew + Serial Old 垃圾回收器组合 |
-XX:+UseParallelOldGC | 指定使用 ParNew + ParNew Old 垃圾回收器组合 |
-XX:+UseConcMarkSweepGC | 指定使用 CMS + Serial Old 垃圾回收器组合 |
-XX:+PrintGC | 开启打印 gc 信息 |
-XX:+PrintGCDetails | 打印 gc 详细信息 |
-XX:+PrintCommandLineFlags | 打印HotSpotVM 采用的自动优化参数 |
JVM内存组成里面最为关键的几个内存
栈内存
只是保存有堆内存的引用地址,而且从一个简单的角度来讲,栈内存可以保存基本类型(int、double)。
堆内存
Java没有采用句柄的模式进行引用,所以他的引用性能是最高的,但是从另外一个角度来讲,堆内存里面又分为了若干个子内存空间:伊甸园区(MinorGC)、存活区、老年代(FullGC、MajorGC)。
方法区
JDK1.8之前叫永久代,之后称为元空间。
全局数据区
也可以认为其规划在堆内存里面,因为会发现全局数据区之中保存的内容有可能是对象,有可能是基本类型,只不过它采用了一种特殊的处理形式而已。
伸缩区、收集器调优原则
从Java8开始取消了永久代,而使用元空间来操作,那么也就是说Java可以直接使用操作系统的内存进行管理,这样就有可能导致每个线程分配的真实的主机内存空间就越大,所以这个时候如果内存不足,操作系统会进行虚拟内存的控制,对于虚拟内存不需要做特别多的处理。
当线程访问量追加,那么JVM就有可能进行不断的内存申请以及不断的内存回收,所以对-Xmx、-Xms的两个参数控制就非常重要。
取消伸缩区 让total = max
优化的关键点优化其堆内存的管理和分配策略。
- 让初始化的空间大小等于整个的堆内存的分配大小
- 如果不相同,那么就需要一直进行空间的判断,而后不断的进行空间的分配
- CMS问题,频繁的CMS会导致性能下降
- 少产生无用的大量内存空间,因为会引发频繁的GC,而频繁的GC会带来CMS问题,那么会导致程序终端程序,所以这个处理的原则之中对于程序员的要求
在Tomcat里面由于其使用基于JVM,所以需要设置一个“JAVA_OPTS”指令,可以将全部的内存供tomcat使用(默认最大可用内存为所有内存的1/4,初始化分配内存为1/64)。
- 少产生无用的大量内存空间,因为会引发频繁的GC,而频繁的GC会带来CMS问题,那么会导致程序终端程序,所以这个处理的原则之中对于程序员的要求
使用G1收集器
如果你的内存过大要使用G1收集器来进行收集