Java底层篇(1.4)
1、JVM
→ Java 对象模型
oop-klass、对象头
在JVM中,使用了OOP-KLASS模型来表示java对象,即:
1.jvm在加载class时,会创建instanceKlass,表示其元数据,包括常量池、字段、方法等,存放在方法区;instanceKlass是jvm中的数据结构;
2.在new一个对象时,jvm创建instanceOopDesc,来表示这个对象,存放在堆区,其引用,存放在栈区;它用来表示对象的实例信息,看起来像个指针实际上是藏在指针里的对象;instanceOopDesc对应java中的对象实例;
3.HotSpot并不把instanceKlass暴露给Java,而会另外创建对应的instanceOopDesc来表示java.lang.Class对象,并将后者称为前者的“Java镜像”,klass持有指向oop引用(_java_mirror便是该instanceKlass对Class对象的引用);
4.要注意,new操作返回的instanceOopDesc类型指针指向instanceKlass,而instanceKlass指向了对应的类型的Class实例的instanceOopDesc;有点绕,简单说,就是Person实例—>Person的instanceKlass—>Person的Class。
instanceOopDesc,只包含数据信息,它包含三部分:
- 对象头,也叫Mark Word,主要存储对象运行时记录信息,如hashcode, GC分代年龄,锁状态标志,线程ID,时间戳等;
- 元数据指针,即指向方法区的instanceKlass实例 (虚拟机通过这个指针来群定这个对象是哪个类的实例。)
- 实例数据;
- 另外,如果是数组对象,还多了一个数组长度
【参考链接】https://www.cnblogs.com/thiaoqueen/p/9314745.html
→ HotSpot
即时编译器、编译优化
部分商用虚拟机中,Java最初通过解析器( Interpreter )解析,当虚拟机发现某个方法或代码块运行的特别频繁时,就把这些代码当成“热点代码”,为了提高热点代码的执行效率,在运行时,即时编译器(Just In Time Compiler)会把这些代码编译成与本地平台相关的机器码,并进行各种层次的优化。
解释器和编译器各有各的优点:
解释器优点:当程序需要迅速启动的时候,解释器可以首先发挥作用,省去了编译的时间,立即执行。解释执行占用更小的内存空间。同时,当编译器进行的激进优化失败的时候,还可以进行逆优化来恢复到解释执行的状态。
编译器优点:在程序运行时,随着时间的推移,编译器逐渐发挥作用,把越来越多的代码编译成本地代码之后,可以获得更高的执行效率。
因此,整个虚拟机执行架构中,解释器与编译器经常配合工作,如下图所示。
【参考链接】https://www.cnblogs.com/linghu-java/p/8589843.html
→ 虚拟机性能监控与故障处理工具
jps, jstack, jmap, jstat, jconsole, jinfo, jhat, javap, btrace, TProfiler
名称 | 主要作用 |
---|---|
jps | jvm process status tool,显示指定系统内所有的hotspot虚拟机进程 |
jstack | stack trace for java ,显示虚拟机的线程快照 |
jmap | memory map for java,生成虚拟机的内存转储快照(heapdump文件) |
jstat | jvm statistics monitoring tool,用于收集hotspot虚拟机各方面的运行数据 |
jinfo | configuration info for java,显示虚拟机配置信息 |
jhat | jvm heap dump browser,用于分析heapmap文件,它会建立一个http/html服务器让用户可以在浏览器上查看分析结果 |
【参考链接】https://blog.csdn.net/baidu_39299382/article/details/80330476
Arthas
Arthas(阿尔萨斯)是阿里巴巴开源的 Java 诊断工具,深受开发者喜爱。
当你遇到以下类似问题而束手无策时,Arthas 可以帮助你解决:
这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
是否有一个全局视角来查看系统的运行状况?
有什么办法可以监控到JVM的实时运行状态?
Arthas 采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。