JVM运行时数据内存区域划分
运行时数据区域 是java启动时在计算机内存中的数据区域
运行时数据区域会把计算机内存进行划分分为以下几种内存区域
1.程序计数器 Program Couter Register
2.java 堆 Java Heap(Heap)
3.虚拟机栈 VM Stack (Stack)
4.方法区 Method Area (Stack)
5.本地方法栈 Native Method Stack (Stack)
6.执行引擎
7.本地借口 / 本地方法库
程序计数器
程序计数器是一款较小的内存 他的作用是在当前线程执行的字节码的执行指示器 字节码解释器是通过改变计数器的值来选取下一条要执行的字节码指令 分支 循环跳转异常 线程恢复等基础功能需要依赖这个计数器完成
程序计数器是线程私有的 每条线程都有一个独立的程序计数器 各条线程之间计数器不互相影响 独立存储 所以称为私有内存
JAVA 虚拟机栈
JAVA虚拟机栈(JAVA Virtual Machine Stack)是线程私有 他的生命周期与线程相同 每个方法执行时都会创建一个 Stack Frame (栈帧) 用于存储局部变量表 操作栈 动态链接 方法出口 等信息
方法调用直至执行完成的过程是一个栈帧在虚拟机栈中入栈到出栈的过程
现在所指的Java栈就是java虚拟机栈也可以说是局部变量在运行时数据区的存放地方并且局部变量表所需要的内存空间是在编译期间完成分配的
本地方法栈
虚拟机栈为虚拟机JAVA方法(字节码)服务的 而本地方法栈择是为虚拟机用到的Native(本地)方法服务的
Sun HotSpot 虚拟机 直接就把本地方法栈和虚拟机栈合二为一
Java堆
Java堆是被所有线程共享的一块内存区域 在虚拟机启东市创建 唯一目的是为了存放对象的实例几乎所有对象*都要在这里分配内存
java堆可以处于物理上不连续的内存空间中 只要是逻辑上连续的即可
方法区
方法区和Java堆一样是线程共享的内存区域 用于存储已被虚拟机加载的类的信息 常量 静态变量 及时编译器编译后的代码等数据
方法区别名 Non-Heap (非堆)
因为GC收集行为在这个区域比较少出现 所以这个区域又称为永久代 但是并不是数据进入了方法区就真的是永久存在了而是在这个区域的内存主要回收的姆比哦啊是针对常量池的回收和堆类型的卸载
运行时常量池(Runtime Constant Pool)
运行时常量池是方法区的一部分 Class 文件中除了有类的版本 字段 方法 接口等信息意外 还有一项信息是常量池 Constant Pool Table 用于存放编译期间产生的各种字面量和符号引用 这部分内容会在类加载后存放到方法区的运行常量池内
Class文件中除了符号引用歪 还会把编译出来的直接引用也春处在运行时常量池中
Class文件常量池在运行期间也可以将新的常量放入池中 便是String 类下的 intern() 方法
直接内存(Direct Memory)
直接内存并不是虚拟机运行时数据区的一部分 也不是虚拟机规范中定义的内存区域 但是这部分内存也被频繁使用也可导致OOM (Out Of Memory Error)