jvm学习小结一

一、java技术体系

1、java技术体系组成:java语言、jvm、class字节码、java api、各种第三方框架。

2、jdk(java Development Kit):java语言、jvm、java api。jdk是用于支持java程序开发的最小环境。

3、jre(java Runtime Environment):java se api、jvm。jre是支持java程序运行的标准环境。

4、java技术体系可分为4个平台,包含的java api内容有大有小:Java Card,运行在小内存设备上;Java ME(Micro Edition),支持移动终端,java api有所精简;Java SE(Standard Edition),支持桌面级应用,含有完整的java核心api;Java EE(Enterprise Edition),对java se api做了大量扩充,扩展api一般以javax.*作为包名。

二、运行时内存区域

  • 堆:所有线程共享,存放对象实例。
  • 方法区:线程共享,存储被加载的类信息、静态变量、常量、即时编译器编译后的代码等数据。
  • 运行时常量池:方法区的一部分,class文件的常量池(字面常量和符号引用)+运行时产生的常量,其中符号引用又包含三类:类、接口的全限定名,字段名称和描述,方法名称和描述。
  • 程序计数器:  当前线程执行的字节码的行号指示器。
  • 虚拟机栈:每一个方法对应一个栈帧,栈帧 = 局部变量表、操作数栈、动态链接、方法出口信息。栈帧的大小编译时已经确定了。
  • 本地方法栈:为Native方法提供的栈。
  • 直接内存:不属于jvm管理,但是在nio中,会使用native方法申请堆外内存,并在java堆中保存其引用。

其中,堆和方法区是所有的线程所共享的,而虚拟机栈、本地方法栈和程序计数器是各线程所独享的。

在HotSpot虚拟机实现中,直接将虚拟机栈和本地方法栈合二为一;将方法区放入堆中,被称为永久代。

三、HotSpot虚拟机

3.1、对象的创建

1、当使用new创建普通java对象时,先检查常量池中该类的符号引用,看该类是否被加载、解析和初始化,如果没有则加载该类。

2、分配内存,全部初始化为零值。

3、执行<init>方法初始化对象。

3.2、对象的内存布局

对象在内存中存储的布局分为3块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

对象头:分为两部分。第一部分存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,长度为32bit或64bit,称为Mark Word。因为信息太多,Mark Word存不下,因此对象在不同状态下,Mark Word表示的信息不同。第二部分是该对象的类型指针,即对象指向它的类元数据(我认为是Class对象)的指针,并不是所有虚拟机都在对象数据中保留类型指针(比如如果有句柄的话,就放入句柄中)。

实例数据:父类继承下来和子类定义的字段信息。

对齐填充:HotSpot中对象起始地址必须是8字节的整数倍,因此不足的需要对齐填充。

3.3、对象的访问定位

java程序需要通过对象引用来操作对象,而通过对象引用访问的方式有两种:使用句柄或直接指针。

句柄:在堆中分出句柄池,对象引用指向句柄池中的句柄,句柄含有实例数据的指针和类型数据的指针。

直接指针:对象引用直接存放对象在堆中的地址,这是HotSpot虚拟机使用的方式。

参考:

《深入理解java虚拟机》周志明

猜你喜欢

转载自blog.csdn.net/jdbdh/article/details/82495735