Java性能优化权威指南-JVM概述和监控调优
JVM概述和监控调优
- 1、JVM概述
- 1.1 HotSpot VM基本架构
- 1.2 HotSpot VM运行时
- 1.2.1 命令行参数解析
- 1.2.2 VM生命周期
- 1.2.3 VM加载类
- 1.2.4 类数据共享
- 1.2.5 解释器
如有侵权,请联系~
如有错误,也欢迎批评指正~
本篇文章大部分是来自学习《Java性能优化权威指南》的笔记
1、JVM概述
1.1 HotSpot VM基本架构
HotSpot VM主要分为三部分:HotSpot VM运行时、JIT编译器、垃圾回收器。即时编译器和垃圾回收器是可插拔的,可以选择适合自己的。
早期的HotSpot VM是32位的,内存限制为4G。但随着现代内存越来越大,HotSpot VM也支持64位。64位的VM除了增加了内存空间,也会带来一些性能的问题:
- 对象的引用从原来占用4字节32位到8字节64位,占用空间大,触发GC
- 解决方案:Java支持指针压缩,可以将64位压缩为32位【其实是35位,因为对象结构中填充部分的存在,对象的开头指针都是8的整数倍,即后面3位都是0,可以不存储。这种要求Java的内存不能超过32G。超过就会自动关闭指针压缩】
1.2 HotSpot VM运行时
HotSpot VM运行时担任很多责任:命令行参数解析、VM生命周期、类加载、Java本地接口…
1.2.1 命令行参数解析
命令行参数从使用角度可以分为两种:一种给启动器使用的;一种给启动的HotSpot VM使用。
使用什么垃圾回收器、即时编译器这些参数都是交给启动器,在启动的时候决定使用那种GC、JIT等;例如堆的大小、栈的大小等等都是交给启动器启动后的HotSpot VM使用。
命令行中的参数从稳定性角度分为三类:标准选项、非标准选项(-x)和非稳定选项(-XX)。
1.2.2 VM生命周期
启动HotSpot VM的是启动器,HotSpot VM中启动器不止一个,例如java命令、javaws命令等等。
启动器启动的步骤一般为:
- 解析命令行参数:通过命令行参数获取堆大小、JIT编译器类型等等
- 设置堆大小和JIT编译器
- 设定环境变量如LD _LIBRARY_PATH和CLASSPATH
- 获取Main-class
- 新创建一个线程,通过JNI接口JNI _CreateJavaVM创建HotSpotVM
- 加载Main-class
- HotSpot VM会通过JNI接口CallStaticVoidMethod方法调用main方法
1.2.3 VM加载类
VM需要加载、链接和初始化Java类和Java接口。加载阶段是HotSpot VM和特定类加载器如java. lang .ClassLoader 之间相互协作的过程。
类的加载符合双亲委派机制,优先级:启动类加载器>扩展类加载器>系统类加载器【应用类加载器】。
Java类型是由全限定类名和类加载器共同决定的。即即使两个类的全限定类名一样,但是不是同一个类加载器加载的,那么也认为是两个不同的java类。阿里巴巴的pandora实现不同中间件类的隔离就是通过这种方式,不同的中间件有自己的类加载器。
1.2.4 类数据共享
将一些核心的类如java.lang包下的类在启动之前先打包成一个归档文件,在打包的时候就会对类进行加载解析,等到使用这个类的时候就会直接从归档文件中读取,不用再加载解析类文件。
创建归档文件:
java -Xshare:dump -XX:+UseCompressedOops
使用CDS:
java -Xshare:on -jar myapp.jar
1.2.5 解释器
针对于C语言这种编译语言,他们直接将代码编译成机器所识别的机器码;而Java为了实现一次编译到处运行,Java是解释性语言。Java将代码首先编译成字节码文件【介于代码和机器码之间】。代码执行的时候就会将字节码转换为机器码进行执行。而这个转换就是通过模版表TemplateTable。为每个机器码通过对应的机器码函数生成机器码。参考:JVM之模板解释器