无招胜有招之Java进阶JVM(一)

无招胜有招之Java进阶JVM(一)

 

Class文件格式:Java虚拟机中定义的Class文件格式。每一个Class文件都对应着唯一一个类或接口的定义信息,但是相对地,类或接口并不一定都得定义在文件里(譬如类或接口也可以通过类加载器直接生成)。我们只是通俗地将任意一个有效的类或接口所应当满足的格式称为“Class文件格式”,即使它不一定以磁盘文件的形式存在。

推荐:https://blog.****.net/tyyj90/article/details/78472986

无招胜有招之Java进阶JVM(一)

再说内存结构前先说一下JVM的基本结构:

 

  1. 类加载器(ClassLoader):在jvm启动时或者在类运行时将需要的class文件加载到JVM中。详细后面我会在另写一篇博客介绍。
  2. 执行引擎:负责class文件中包含的字节码指令。(同上,详细后面我会在另写一篇博客介绍)。
  3. 内存区(也叫作运行时数据区):是在jvm运行的时候操作所分配的内存区。主要划分为以下5个区域:

 

无招胜有招之Java进阶JVM(一)

  1. 程序计数器(PC Register):坦白来说:就是用于保存当前线程执行的内存地址。由于JVM程序是多线程执行的(线程轮流切换),所以为了保证线程切换回来后,还能恢复原先的状态,就需要一个独立的计数器,记录之前中断的地方,可见程序计数器是线程私有的。
  2. Java栈(JVM Stack):java栈总是和线程关联在一起,每当创建一个线程时,JVM就会为这个线程创建一个对应的栈。在这个java栈中又会包含多个栈帧,每运行一个方法就创建一个栈帧,用于存储局部变量表、操作栈、方法返回值等、每一个方法从调用直到执行完成的过程,就对应了一个栈帧在java栈中入栈到出栈的过程。所以java栈是线程私有的。
  3. 本地方法栈(Native Method Stack):和java栈的作用差不多,只不过是为JVM使用到的native方法服务的
  4. Java堆(Heap):存储Java实例或者对象的地方。这块是GC的主要区域(以后介绍)。从存储的内容我们可以很容易知道,方法区和堆是被所有java线程共享的。
  5. 方法区(Method Area):用于存储类结构信息的地方,包括常量池、静态变量、构造函数等。虽然JVM规范把方法区描述为堆的一个逻辑部分,但它却有一个别名(non-heap非堆),所以不要搞混淆这个问题。方法区中还包含一个运行时常量池(Runtime Constant Pool)

常量池

  即class文件常量池,是class文件的一部分,用于保存编译时确定的数据。

运行时常量池:

Java语言并不要求常量一定只能在编译期产生,运行期间也可能产生新的常量,这些常量被放在运行时常量池中。

类加载后,常量池中的数据会在运行时常量池中存放!

这里所说的常量包括:基本类型包装类(包装类不管理浮点型,整形只会管理-128到127)和String(也可以通过String.intern()方法可以强制将String放入常量池)

【补充】jdk 1.7后,移除了方法区间,运行时常量池和字符串常量池都在堆中。

4.本地方法接口:主要调用c 或c++实现的本地方法及返回结果。

至于直接内存,目前不是很清楚,后期再补。

路漫漫,加油!