JVM性能参数优化及JVM垃圾回收器和JVM垃圾回收算法
前言介绍:一个项目的完美运行,是离不开jvm的优化的,对于一些有经验的程序员来说,由于每个项目的差异,会根据项目的加载情况,做参数调整以及垃圾回收器的选择,下面介绍了一些参数的优化及垃圾回收器的选择和算法介绍,供自己以后参考
一,Java虚拟机基本结构:
类加载子系统: 负责从文件系统或者网络中加载Class信息
方法区: 有时也称为永久区, 用于存放加载的类信息, 以及存放运行时常量池(包括字符串和数字常量, 这部份常量信息是Class文件中常量池部分的内存映射), java8开始称为元数据区, 设置参数也有所不一样
Java堆: 虚拟机启动时建立, 是Java程序最主要的内存工作区域, 几乎所有对象都会存放在Java堆中, 堆是所有线程共享的
直接内存: Java的NIO库允许Java程序使用直接内存(例: DirectByteBuffer, 每次创建和释放都要调用System.gc()), 直接内存是Java堆外直接向系统申请的内存区间, 直接内存的访问优于堆,直接内存不受限于xmx的值, 不过受限于系统的最大内存
垃圾回收系统: 可以对Java堆,直接内存和方法区进行回收, 垃圾回收是隐式的自动完成的, 不用程序手动是释放内存
Java栈: 每个虚拟机线程都有私有的Java栈, 一个线程的栈是在线程创建时创建的, 栈中保存帧, 局部变量, 方法参数 , -Xss用于指定Java栈的空间大小
本地方法栈: 类似Java栈, 用于本地方法的调用, 是Java虚拟机的重要扩展, 即JNI, Java本地接口的调用, 通常是C或C++
PC寄存器: 也被为程序计数器, 是每个线程私有的空间, Java线程正在执行的方法如果不是本地方法, PC寄存器就会指向当前正在被执行的指令, 反之, PC寄存器的值是undefined
执行引擎: Java虚拟核心组件之一, 负责执行虚拟机的字节码, 现代虚拟机的即时编译会将方法编译成机器码后再执行, 会提高执行效率
二,Java虚拟机参数设置:
- 性能参数:
-server
以server模式运行时将拥有:更大、更高的并发处理能力,更快更强捷的JVM垃圾回收机制,可以获得更多的负载与吞吐量
-Xmx
指定java程序的最大堆内存, 使用java -Xmx5000M -version判断当前系统能分配的最大堆内存
-Xms
指定最小堆内存, 通常设置成跟最大堆内存一样,减少GC
-Xmn
设置年轻代大小为512m。整个堆大小=年轻代大小 + 年老代大小。所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
-Xss
指定线程的最大栈空间, 此参数决定了java函数调用的深度, 值越大调用深度越深, 若值太小则容易出栈溢出错误(StackOverflowError)
设定每个线程的堆栈大小。这个就要依据你的程序,看一个线程 大约需要占用多少内存,可能会有多少线程同时运行等。一般不易设置超过1M,要不然容易出现out ofmemory
-XX:PermSize
指定方法区(永久区)的初始值,默认是物理内存的1/64, 在Java8永久区移除, 代之的是元数据区, 由-XX:MetaspaceSize指定
-XX:MaxPermSize
指定方法区的最大值, 默认是物理内存的1/4, 在java8中由-XX:MaxMetaspaceSize指定元数据区的大小
-XX:NewRatio=n
年老代与年轻代的比值,-XX:NewRatio=2, 表示年老代与年轻代的比值为2:1
-XX:SurvivorRatio=n
Eden区与Survivor区的大小比值,-XX:SurvivorRatio=8表示Eden区与Survivor区的大小比值是8:1:1,因为Survivor区有两个(from, to)
-XX:+DoEscapeAnalysis
开启逃逸分析, 逃逸分析的目的是判断对象的作用域是否可能逃逸出函数体, 逃逸分析是栈上分配的技术基础,对于非逃逸对象而言就是一个局部变量, 而对象未发生逃逸时, 虚拟机就有可能进行线上分配, 不是堆上, 栈上分配速度快,并且能避免垃圾回收带来的负面影响, 栈上分配是虚拟机提供的很好的对象分配优化策略
-XX:+EliminateAllocations
开启标量替换(默认打开), 即允许对象打散分配在栈上, 即对象的属性视为独立局部变量进行分配到栈上
-XX:+UseCompressedOops
开启指针压缩
-XX:+AggressiveOpts
启用JVM开发团队最新的调优成果。例如编译优化,偏向锁,并行年老代收集等
-XX:-UseTLAB
关闭TLAB , 默认是打开的
-Djava.awt.headless=true
有时我们会在我们的J2EE工程中使用一些图表工具如:jfreechart,用于在web网页输出GIF/JPG等流,在winodws环境下,一般我 们的app server在输出图形时不会碰到什么问题,但是在linux/unix环境下经常会碰到一个exception导致你在winodws开发环境下图片显 示的好好可是在linux/unix下却显示不出来,因此加上这个参数以免避这样的情况出现.
-XX:+DisableExplicitGC
在程序代码中不允许有显示的调用”System.gc()”。看到过有两个极品工程中每次在DAO操作结束时手动调用System.gc()一下,觉得这 样做好像能够解决它们的out ofmemory问题一样,付出的代价就是系统响应时间严重降低,就和我在关于Xms,Xmx里的解释的原理一样,这样去调用GC导致系统的JVM大起大 落,性能不到什么地方去哟!
-XX