引用一张经典的java 内存模型
用一个用户视角来解释这张图。
一:程序计数器:
字节码解释器会改变程序计数器的值来控制下一条指令执行的字节码指令。是每个线程私有。
二:java 虚拟栈:
他的生命周期和线程是相同的,每个线程执行的时候会创建一个栈。用于 存放:
1,局部变量表
2,操作数栈
3,动态链接
4,方法出口
一个方法的被调用知道执行完毕,就对应一个栈桢的入栈和出栈。
三:本地方法栈
和虚拟机栈的作用很相似,本地方法栈是为了java 程序使用到本地方法(Native)各个虚拟机任意实现。hot spot 是直接合并了
java堆:
java 堆是所有线程共享的一块内存区域,在虚拟机启动是创建,java的对象实例就存放在这里,几乎所有的对象实例都在这里分配内存。(GC是回收没有使用的对象的)
方法区
和java 堆一样是所有线程共享的区域,主要存储的信息是:
1,被虚拟机加载的类型信息
2,常量
3,静态变量
4,即时编译后的代码缓存等数据。
原本是使用永久代来实现方法区,
现在是,直接使用本地内存可以回收常量池和类型的卸载。原本放在方法区的字符串常量池和静态变量移出了. 在1.8以后使用了元空间(meta space)来实现jvm的方法区定义。
运行时常量池:
是方法区的一部分,Class 文件中除了有类的版本、字段、方法、接口等描述信息以外,还有一项信息是:常量池表。用于存放编译时期生成的各种字面量与符号引用。
直接内存:
NIO /IO 的通道,也可以给native 函数使用,native 分配的内存也可以分配在堆外面。