令人放心食用的JVM指南

食前指南

Java程序是交给JVM执行的,所谓Java内存(JVM内存)也就是讲JVM运行时数据区,首先我们先来看下Java程序的执行过程。

令人放心食用的JVM指南令人放心食用的JVM指南

 

菜单1.Method Area(方法区)

方法区也被称为永久代,方法区和堆一样是属于线程共享区域,所以要考虑数据的线程安全问题。方法区包含运行时常量池,在类和接口被加载到JVM之后,对应的运行时常量池就被创建出来。

在方法区中存储了已被虚拟机加载的类的信息(类加载器在类加载时从类文件中提取出来的,比如类的名称、方法信息、字段信息)、静态变量、常量以及即时编译器编译后的代码等数据。

JVM规范中方法区无法满足内存分配需求的时候也会抛出OOM,虽然规范中方法区不必实现垃圾收集,方法区中也是有垃圾回收的,而他回收的对象是废弃常量和无用类。

 

菜单2.Heap(堆)

堆也是线程共享区域,在JVM中只有一个堆。

堆是JVM中内存占用最大的区域,其唯一的用途就是用存放对象实例和数组

 

菜单3.VM Stack(Java栈/虚拟机栈)

Java栈是Java方法执行的内存模型。

Java栈中存放的是一个个的栈帧,每个栈帧对应一个被调用的方法,在栈帧中包括局部变量表、操作栈数、动态链接、方法出口等等。

线程私有,每个线程对应一个Java虚拟机栈,生命周期是与线程共进退。每个Java方法在被调用的时候都会创建一个栈帧,并入栈。一旦完成调用,则出栈。所有的栈帧都出栈之后线程也就完成了自己的使命。

令人放心食用的JVM指南

 

菜单4.Native Method Stack(本地方法栈)

本地方法栈与Java栈的作用和原理非常相似。Java栈是为虚拟机使用到的Java方法服务,而本地方法栈则是为虚拟机使用到的Native服务。

 

菜单5.Program Counter Register(程序计数器)

程序计数器是指CPU中的寄存器也被称为PC寄存器。每个处理器都只会执行一条线程中的指令,因此每个线程都有属于它自己的PC寄存器。

PC寄存器的作用是记录当前线程执行的虚拟机字节码的指令地址,如果该线程在执行一个Native方法,那么指令地址为“Undefined”。

 

特别菜单.Version Difference(版本差异)

JDK1.7版本把运行时常量池、静态变量等等从方法区中移出放在堆中。

JDK1.8版本把方法区剥离出来,放在本地内存里面。简单说就是“元数据区代替了永久代”,“元数据空间并不在虚拟机中,使用的是本地内存”。

令人放心食用的JVM指南

 

点心.Useless(废弃常量和无用类)

废弃常量是指不在任何地方被引用则会被标记成废弃常量。

标记为无用类需要三个条件:

1.Java堆中不存在该类的任何实例对象;

2.加载该类的类加载器被回收;

3.该类对应的java.lang.Class对象不在任何地方被引用,且无法在任何地方通过反射访问该类的方法。

 

饮品.Stack(局部变量表和方法出口)

局部变量表包括了八大数据类和对象引用等,我们平时说的引用所在的栈大都是指局部变量表。

当一个方法执行完之后,要返回之前调用它的地方,因此栈帧中必须保存一个方法返回的地址,也就是方法出口。

 

 

厨师长语录:

饭菜是否合胃口,请在下方留言,我不一定会看,看了也不一定会回复,因为我每天都要加班。

令人放心食用的JVM指南