javaSE复习之——java的五大内存区域

五大内存区域

  • 虚拟机栈

  • 本地方法栈

  • 方法区

  • 寄存器区

    ps:我们主要用:虚拟机栈、方法区、堆

Java程序运行过程

  • 1、加载字节码文件到方法区(.class文件)
  • 2、程序代码依次进栈(jvm执行main方法)

堆(heap):

最大的一块内存,存放对象实例的地方

  • 1、Java堆是垃圾收集器管理的主要区域,也称GC堆。
  • 2、Java堆物理上可不连续,逻辑上连续。
  • 3、堆中没有完成实例分配,并且对也无法在扩展时抛出 OutOfMemoryError异常

虚拟机栈(stack):

java方法执行时的内存模型

  • 栈帧

    1、每个方法都会在虚拟机栈中创建一个对应的栈帧,用于存储局部变量表操作数栈动态链接方法出口等信息。

    2、一个方法的调用到结束就对应这一个栈帧从虚拟机栈入栈到出栈

  • 局部变量表

    1、存放编译期可知在方法中各种基本数据类型对象的引用,基本数据类型直接存值, 引用数据类型存地址。

#本地方法栈:

本地方法栈和虚拟机栈作用相似,虚拟机栈为虚拟机执行java方法(字节码)服务,本地方法栈为jvm使用Native方法服务

  • 本地方法 关键字 native ,这些方法一般用来调用本地方法库中的方法这些方法,操作底层大多用C 实现。

  • 有的虚拟机将本地方法栈虚拟机栈合在一起,如HotSpot

方法区:

  • 存已经被虚拟机加载的类信息(Class对象)、常量静态变量、即时编译器JIT编译过后的代码数据

  • jdk 1.7、1.8 对方法区做出了修改,1.8 取消了方法区。

    1、方法区被Java虚拟机规范描述为堆的一个逻辑部分,但它不是堆,有一个别名叫非堆Non-Heap

    2、 jdk1.6 及之前方法区位于永久代(PermGen),永久代和堆相互隔离。

    3、方法区可以不需要连续的内存空间,也可以固定大小,也可以扩展,也可以不实现垃圾收集,如果实现则主要针对常量池的回收和类型的卸载。

  • 运行时常量池

    1、在方法区,用来存放编译期生成的各种符号引用和字面量

    2、编译期将各种符号引用字面量放置在class文件的常量池中,解析后在运行时常量池,字符串在方法区的字符串常量池中(1.7之前),方法运行时复制到局部变量表中。1.7开始字符串常量池被移入堆中。

    符号引用: String ss = “asdsfg” ss这个符号就是符号引用。解析阶段解析为直接引用

    字面量: 值本身 如 asdfg

    常量池中有各种虚拟机正常运行需要的字符串,所以有些即使不创建也还会存在于字符串常量池中如”java”。

寄存器(程序计数器):

  • 占用较小的一块内存空间,当执行Java方法时记录正在执行的虚拟机字节码指令地址,如果执行Native方法则计时器值为空。