JVM知识点学习总结

一.JVM内存结构

先看一张图,这张图能很清晰的说明JVM内存结构布局。

JVM知识点学习总结

    JVM内存主要分为堆内存、方法区以及栈内存,堆内存是JVM中占用空间最大的区域,它又包括年轻代、老年代,而年轻代又可以划分为EdenSpace空间、FromSpace空间、ToSpace空间,一般按照8:1:1对年轻代进行划分;

JVM和系统调用之间的关系如下图所示:

JVM知识点学习总结

方法区和堆是所有线程共享的内存区域;而java栈、本地方法栈和程序计数器是运行时线程私有的内存区域。

1 Java堆(Heap)

对于大多数应用来说,Java堆(Java Heap)是Java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。

2 方法区(Method Area)

方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据

3 栈(Stacks)

(1)JVM栈(JVM Stacks)

与程序计数器一样,Java虚拟机栈(Java Virtual Machine Stacks)也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

(2)本地方法栈(Native Method Stacks)

本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。虚拟机规范中对本地方法栈中的方法使用的语言、使用方式与数据结构并没有强制规定,因此具体的虚拟机可以*实现它。甚至有的虚拟机(譬如Sun HotSpot虚拟机)直接就把本地方法栈和虚拟机栈合二为一。与虚拟机栈一样,本地方法栈区域也会抛出*Error和OutOfMemoryError异常。

4 程序计数器

程序计数器(Program Counter Register)是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。 


二.JVM类加载机制

类加载:JVM把java的class类加载到内存中进行验证、准备、解析、初始化等一系列操作,形成JVM可以使用的Java类型的过程。

1.类加载流程图

JVM知识点学习总结


2.加载

(1)将class文件加载在内存中

(2)将静态的数据构(数据存在于class文件的结构)转化成方法区中运行时的数据结构(数据存在于JVM时的数据结构)

(3)在堆中生成一个代表这个类的java.lang.Class对象,作为数据访问的入口

3.链接

链接就是将Java类的二进制代码合并到Java的运行状态中的过程

验证:确保加载的类符合JVM规范与安全

准备:为static变量在方法区中分配空间,设置变量的初始值。例如static int a=3,在此阶段a会被初始化为0

解析:虚拟机将常量池的符号转换成直接引用,例如a为常量池的一个值,直接把a替换成存在于内存中的引用地址

4.初始化

初始化阶段是执行类构造器<clinit>()方法,在类构造器方法中,它将由编译器自动收集类中的所有变量的赋值动作和静态变量与静态语句块static{}合并

5.使用

正常使用

6.卸载

GC把无用的对象从内存中进行回收

参考:JVM内存结构

    JVM类加载机制