Jvm以及Jvm性能参数优化
2016-04-03 22:53
281 查看
一,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虚拟机参数设置:
(1)性能参数:-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:+UseBiasedLocking
偏向锁,启用一个优化了的线程锁,我们知道在我们的appserver,每个http请求就是一个线程,有的请求短有的请求长,就会有请求排队的现象,甚至还会出现线程阻塞,这个优化了的线程锁使得你的appserver内对线程处理自动进行最优调配。
(2)垃圾回收相关:
见Jvm垃圾回收器详细
(3)调试参数:
-verbose:gc
表示输出虚拟机中GC的详细情况
-Xloggc:
指定gc以文件输出(默认在控制台), 后面跟日志文件路径
-XX:+PrintGC
加上参数可以在输出日志中可以查看垃圾回收前后堆的大小, 即打印gc日志
-XX:+PrintGCDetails
打印gc日志的更加详细的信息
-XX:+PrintHeapAtGC
打印每次GC前后堆的信息
-XX:+PrintGCTimeStamps
输出GC发生时,gc发生的时间
-XX:+PrintGCApplicationConcurrentTime
打印应用程序的执行时间
-XX:+PrintGCApplicationStoppedTime
可以打印应用程序由于GC而产生的停顿时间
-XX:+PrintReferenceGC
跟踪系统内的软引用,弱引用,虚引用和Finallize队列
-XX:+TraceClassLoading
打印类加载时的相关信息
三, Java堆:
1, 堆内存(heap)和 Permanent区。(1)Java堆内存(heap):
–是 JVM 用于分配 Java 对象的内存,包含活动对象和不可用对象
–堆大小通常是在服务器启动时使用 java 命令中的 –Xms(最小) –Xmx(最大)标志来定义。
(2)Permanent区:(永久区)
–指内存的永久保存区域
–是Sun JDK和HP JDK用来加载类(class)和Meta信息的专门的内存区
–这个区域不归属Java堆内存(heap)范围
–Class在被Loader时就会被放到此,如果Java应用很大,例如类(class)很多,那么建议增大这个区域的大小来满足加载这些类的内存需求
–通过–XX:PermSize=***M –XX:MaxPermSize=***M调整
2, Java堆的结构:(新生代+老年代)
如上图, 如果 -Xms指定的值比-Xmx的小,那么两者的差值就是Virtual内存值。随着程序的运行,Eden区、 Tenured区和Perm区会逐渐使用保留的Virtual空间。
Young Generation 新生代, 即图中的Eden + From Space + To Space
Eden 存放新生的对象
Survivor Space 有两个,存放每次垃圾回收后存活的对象
Old Generation Tenured Generation 老年代, 即图中的Old Space 主要存放应用程序中生命周期长的存活对象
Jvm相关书籍推荐:<<实战Java虚拟机—JVM故障诊断与性能优化 >>
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树