java源码解析之jvm

    由于种种原因导致计划变更,中途回了一下老家,感慨也是颇多。   

    不得不深夜加班,以期完成既定计划。   随着学习的推进,越发感觉到基础的重要性。  特地查阅了下Jvm的运行原理。  网上的教程数不胜数。 而且其作为一门成熟的技术发展完善了十余年,本身也具有相当的复杂度。   由于之前的学习经历,因此我选择在外网上面进行相关知识的学习。

    《java源码解析之jvm》

    不得不说,质量还是不错的。   这里给出的组成部分有:  类加载器子系统,数据内存结构,执行引擎,本地方法接口,以及本地方法库。    

    之前有过丁点了解的是类加载器: 不得不说它对我们理解java还是有十分显著的作用的额。 如双亲委派机制,也是理解其它一些第三方框架的一个比较关键的地方吧。 

    诸如内存结构,jni等都是有所耳闻,却不曾去查询相关资料。 

《java源码解析之jvm》

    这里将类加载分为三个部分,加载,链接,初始化。    需要注意  这里的加载采用了双亲委派机制,其应该是由面向对象的特性的所决定的。   之前不曾了解的是 链接,这里将链接分为了三个部分,合法性验证(针对于伪代码),准备(应该是初始化一些常量和静态变量),解析。   之后再是初始化。  

    初始化有些神奇的是,它是由语法特性所决定的,并非调用的方法初始化。  同时,需注意初始化时,似乎时java.lang.Class泛型的一个具体的初始化。  这点可以在java.lang.Class类中的定义看到,他是一个泛型类。   很多的反射相关的内容也是由Class所提供的核心接口。 

《java源码解析之jvm》

《java源码解析之jvm》

    上两张图显示了java的内存结构。   这里将其分为了:方法区,堆区, 栈区,寄存器,本地方法栈。 

    方法区中,由类的数据构成,这里应该是指成员变量,以及成员方法。  

    堆中,主要保存的时对象,也就是类初始化后的一个实例,这里可以可以是单例,也可以不是。 只是当某一个类被初次调用时会被加载并初始化。  后面应该调用的时候,应该是采用享元模式copy一份吧我想。 

    栈中,保存了很多的栈帧。栈帧是栈中的一种数据结构,位于栈的顶部好像。     需注意栈帧中包括了本地方法栈。 这个应该是一个比较高级别的一个内存,静态变量和静态方法貌似也位于栈中。  此外,类也位于栈中。      在之前看线程章节的时候,了解到其实所有的线程都有自己的栈,以及相应的栈帧,也就是  我们平时的  e.printStackTrace()看到了那些信息。   并且每个线程的栈的信息,在某一时刻都是可以得到的。   

    寄存器中,这里采用了t1,t2,t3的记录方式。  这里不是很懂了,有一种猜测是时钟周期,即当前周期寄存器的试用期归自己。  另一种猜测是thread,也就是线程。   我更倾向于后者。   

    本地方法栈,一些c,甚至有可能是汇编的函数吧,它们是面向过程的,或者是面向指令的,因此优化应该是他们的主要任务,它们是亲Pc的。    而对于面向对象的语言,它们的主要目的则是为了简便,易用,扩展性,灵活性等等,因此它们是亲人类的,它们的主要目的在于简化人们的工作,因此有时牺牲一些效率是在所难免的。   也因此,很多的操作都是基于本地方法而进行最终的一个逻辑实现的。   所以c很重要,java也很重要,汇编也很重要。 

《java源码解析之jvm》

    改图是执行引擎的相关内容,这里将它看作了这样的几个部分:翻译机(解释),即时编译技术,垃圾回收器,hotspot分析器(优化性能),并且辅以本地方法接口和本地方法的接口库文件完成执行逻辑。 

    这里需要注意,jvm对堆栈的这些分配默认会有一些大小的限制,好像一个2g内存只能开4个jvm的实例,否则会溢出还是怎样来着。 因此我们经常听说比如python或者  php等语言会说可以开很多个,但是Java一般情况下就开4个的原因。   具体的数据由于过了一段时间忘了,但是确实有这么个事。嘿嘿。

    原文作者:java源码分析
    原文地址: https://blog.csdn.net/qq_36285943/article/details/80316799
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞