java虚拟机 (4)

在G1收集器出现之前,垃圾收集的目标范围要么是整个新生代,要么就是整个老年代,要么就是整个java堆。而G1它可以面向堆内存任何部分来组成回收集进行回收,衡量标准不再是它属于哪个分代,而是哪块内存中存放的垃圾数量最多,回收收益最大,这就是G1收集器的Mixed GC模式

如果不去计算用户线程运行过程中的动作G1收集器的运作过程大致可分为四个步骤:

初始标记:仅仅标记一下GCRoots能直接关联到的对象,并且修改TAMS指针的值,需要停顿线程但耗时很短。

并发标记:从GC Root开始对堆中对象进行可达性分析,当对象图扫描完以后还要重新处理SATB记录下的并发时有引用变动的对象。

最终标记:对用户线程做另一个短暂的暂停。用于处理并发阶段遗留下少量的SATB记录

筛选回收:对各个Region的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划

类文件结构

java虚拟机平台无关性”一次编译,到处运行“。java虚拟机提供语言无关性。其他语言的程序编译成.class的字节码文件皆可以在java虚拟机中运行。

魔数与Class文件

每个Class文件的头4个字节被称为魔数,它的唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件。Class文件的魔数值为0xCAFEBABE。紧接着魔数的4个字节存储的是Class文件的版本号:第5和第6个字节是次版本号,第7和第8个字节是主版本号。java版本号从45开始。

常量池

紧接着主、次版本号之后的是常量池的入口,常量池可以比喻为Class文件里的资源仓库,它是Class文件结构中与其他项目关联最多的数据。由于常量池中的常量数量是不固定的,所以常量池的入口需要放置一个u2类型的数据,这个容量计数是从1而不是0开始的。常量池中主要存放的两大类常量:字面量和符号引用

访问标志

在常量池结束以后紧接着的2个字节代表访问标志,用于识别一些类或者接口层次的访问信息包括这个Class是类还是接口;是否定义为public类是否定义为abstract类;如果是类的话是否被声明为final等等

类索引、父类索引与接口索引集合

Class文件中由这三项数据来确定该类型的继承关系。类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名。接口索引集合就用来描述这个类实现了哪些接口。

字段表集合

字段表用于描述接口或者类中声明的变量。

方法表集合

描述方法,与字段的描述基本类似。方法里的java代码经过javac编译器编译成字节码指令之后,存放在方法属性表集合中一个名为”Code“的属性里面。

属性表集合

Class文件、字段表、方法表都可以携带自己的属性表集合,以描述某些场景专有的信息

1.Code属性

java程序方法体里面的代码经过Javac编译器处理之后,最终变为字节码指令存储在Code属性内。

2.Exceptions属性

Exceptions属性的作用是列举出方法中可能抛出的受查异常,也就是方法描述时在throws关键字后面列举的异常。

3.LineNumberTable属性

用于描述Java源码行号与字节码行号之间的对应关系。如果选择不生成,堆栈将不会显示出错的行号,在调试程序时也无法按照源码行来设置断点。

4.LocalVariableTable及LocalVariableTy p eTable属性

LocalVariableTable属性用于描述栈帧中局部变量表的变量与Java源码中定义的变量之间的关系。在JDK 5引入泛型之LocalVariableTable属性增加了一个“姐妹属性”—— LocalVariableTy p eTable。这个新增的属性结构与LocalVariableTable非常相似,仅仅是把记录的字段描述 符的descrip tor_index替换成了字段的特征签名(Signature)。对于非泛型类型来说,描述符和特征签名能描述的信息是能吻合一致的,但是泛型引入之后,由于描述符中泛型的参数化类型被擦除掉[3],描 述符就不能准确描述泛型类型了。因此出现了LocalVariableTy peTable属性,使用字段的特征签名来完 成泛型的描述。

5 . SourceFile及SourceDebugExtension

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwgdz.html