在这里我们先明白一个概念, JVM是虚拟机的规范,HotSpot是jvm的具体实现,类似于接口和实现类的关系;HotSpot 最初由Sun开发,现在由Oracle拥有。JVM规范还有其他实现,例如JRockit,IBM J9 等等。
jvm性能调优的最基本条件
就是要减少垃圾回收机制的回收次数,因为每次回收的时候,其他工作线程都会停顿一段时间,gc需要集中清理垃圾内存就必须暂停工作线程,但是我们人为是看不出区别的;
调优注意项
- 堆初始值(Xms)一定要和堆的最大值(Xmx)设置成一样的,如果不相等的话,会造成垃圾回收机制一直不停地在回收,因为空间太小了,不停地去申请内存并进行回收,大大降低了系统性能,因为垃圾回收机制和设置的最大堆内存(Xmx)无关,只和初始堆内存(Xms)有关;
- 垃圾回收机制的回收次数,跟初始堆内存(Xms)有关系,Xms越小,回收越频繁
- 新生代的内存一定要比老年代的内存小,因为老年代里面的对象已经是经过考验了才会进来的, 把老年代设置大一点是为了减少回收老年代内存的次数,尽量把垃圾回收都在新生代里面去做;
- jvm 调优主要调整的是 堆的内存, 因为栈内存是根据线程走的,所以每次线程走完之后,栈内存的空间就自动释放了;
性能调优常用参数说明
-XX:+PrintGC 每次触发GC垃圾回收的时候打印相关日志
-XX:+PrintGCDetails 更详细的GC日志
-XX:+UseSerialGC serial收集器串行回收
-XX:+UseParNewGC parNew收集器并行回收
-XX:+USeParNewGC parallel收集器并行回收
-XX:+UseConcMarkSweepGC cms收集器 并行回收
-XX:+UseG1GC g1收集器 并行回收
-Xms 堆初始值
-Xmx 堆最大内存 默认4个G 使用方式: -Xmx20m
-Xmn 新生代堆最大值
-Xss5m 线程最大调用深度,默认1m
-XX:SurvivirRatio=4 设置新生代 eden区和 survivor区的空间比例 默认4 : 1 ,如果需要设置成2:1这么写就行了 :-XX:SurvivirRatio=2
-XX:NewRatio=2 // 新生代和老年代的占比默认1:2 , -XX:NewRatio=2表示设置为 1:2
-XX:+HeapDumpOnOutOfMemoryError // 表示当JVM发生OutOfMemoryError 异常时,自动生成DUMP文件。文件默认放到与项目目录同级的文件夹中
-XX:HeapDumpPath=${目录} // 表示生成DUMP文件的路径,也可以指定文件名称,例如:-XX:HeapDumpPath=${目录}/java_heapdump.hprof。如果不指定文件名,默认为:java_<pid>_<date>_<time>_heapDump.hprof。
-XX:+PrintCommandLineFlags // 查看程序使用的默认JVM参数 包括 初始堆大小(InitialHeapSize)、最大堆内存大小(MaxHeapSize)、垃圾收集器(UseSerialGC)
在java 中查看内存使用情况
1、在java代码中添加以下代码
// 在java中获取内存使用情况
Runtime.getRuntime().maxMemory(); // 获取堆最大内存
Runtime.getRuntime().freeMemory(); // 获取可用内存
Runtime.getRuntime().totalMemory(); //获取已使用内存
2、配置参数 -XX:+PrintGCDetails
代码执行完后会打印内存相关的日志信息
3、配置参数 -XX:+PrintCommandLineFlags,可查询jvm信息 包括 初始堆大小(InitialHeapSize)、最大堆内存大小(MaxHeapSize)、垃圾收集器(UseSerialGC)