《JVM》(四)Class类文件结构,非Class类对象的创建

Class类文件结构

class文件是一组以8字节为单位的二进制流,只有两种数据类型:无符号数(基本数据类型),表(复合数据类型)

魔数

版本号

常量池(占class空间最大的数据之一,从1开始计数)

1.字面量 :接近于java层面的常量概念,如字符串,声明为final的常量

2.符号引用:类和接口的全限定名,字段和方法的描述符

字段描述符:描述字段数据类型

方法描述符:描述方法参数列表和返回值

访问标志

类索引,父类索引,接口索引集合

字段表集合(描述接口或类中声名的变量,不包括方法中的局部变量)

方法表集合

属性表集合(如,方法表,属性表都可以带有自己的属性表,如code属性存方法的代码信息)


对象的创建(非Class类)

        0.准备工作,这个指令的参数是否可以在常量池中定位到一个类的符号引用,检查这个类是否已经被加载,解析初始化,如果没有,先执行相应的类加载过程

1.分配内存(堆中)

2.分配的内存空间都初始化为零值

3.init根据程序员的意愿初始化


分配内存

        对象所需内存的大小在类加载完成后便完全确定(JVM可以通过普通Java对象的类元数据信息确定对象大小);

        为对象分配内存相当于把一块确定大小的内存从Java堆里划分出来

        1. 指针碰撞

                如果Java堆是绝对规整的:一边是用过的内存,一边是空闲的内存,中间一个指针作为边界指示器;

                分配内存只需向空闲那边移动指针,这种分配方式称为"指针碰撞"(Bump the Pointer);

        2. 空闲列表

                如果Java堆不是规整的:用过的和空闲的内存相互交错;

                需要维护一个列表,记录哪些内存可用;

                分配内存时查表找到一个足够大的内存,并更新列表,这种分配方式称为"空闲列表"(Free List);

        Java堆是否规整由JVM采用的垃圾收集器是否带有压缩功决定的;

        所以,使用Serial、ParNew等带Compact过程的收集器时,JVM采用指针碰撞方式分配内存;而使用CMS这种基于标记-清除(Mark-Sweep)算法的收集器时,采用空闲列表方式;


对象的访问定位

1.通过句柄访问对象

                  image.png

好处:reference中存的是稳定的句柄地址,在GC时对象被移动只会改变实例数据指针,而reference本身不需要改变

2.通过直接指针访问对象

                 image.png

好处:访问速度快



猜你喜欢

转载自blog.51cto.com/13580976/2148191
今日推荐