详图(一图看清 java 内存模型_查看内存模型java-CSDN博客)
1、方法区(所有线程共享数据)
方法区是线程共享得的区域。它用于存储已被虚拟机加载的类型信息、常量、静态变量及时编译器编译后的代码缓存等数据。运行时常量池是方法区的一部分。Class文件中除了有类的版本,字段,方法,接口等描述信息外,还有一项是常量池表。
2、堆(所有线程共享数据)
java虚拟机启动时候创建的,该区域的唯一目的就是存放对象实例,基本所有的对象实例都是存放在堆中。即时编辑技术,逃逸性分析技术等会出现对象实例不在堆中。java堆是GC的内存区域。
3、虚拟机栈(线程隔离的数据)
虚拟基栈的生命周期和线程相同。虚拟机栈描述的是java方法执行的线程内存模型:每个方法被执行的时候,java虚拟机栈都会同步创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每一个方法被调用至执行结束的过程对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。局部变量表存放了编译器期可知的各种基本数据类型和对象引用。这些数据类型是在局部变量表中的存储空间以局变量槽来表示,局部变量表所需的内存空间在编译期间完成分配。当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全确认的,在方法运行期间是不会该表局部变量表的大小(指的是变量槽的数量),有StackOverflowError和OutOfMemoryError异常。
4、本地方法栈(线程隔离的数据)
和java虚拟机栈类似,区别在于本地方法栈是使用到本地(native)方法服务。
5、程序计数器(线程隔离的数据)
程序计数器是一块较小的内存空间,它记录着当前线程所执行的字节码的行号指示器。
字节码解释器工作就是通过改变这个计数器的值来选取下一条执行的字节码指令。
程序控制流指示器,分支,循环,跳转,异常处理,线程恢复等基本功能都依赖这个计数器来完成。
如果一个线程正在执行某个java方法,该线程的程序计数器记录的是正在执行的虚拟机字节码指令的地址;如果执行的本地方法(native),程序计数器的值是Undefined。程序计数器是唯一没有OutOfMemoryError的区域。
6、直接内存
通过Native函数库直接分配堆外内存,然后通过存储在java堆中DirectByteBuffer对象作为这块内存的引用进行操作避免了java堆和Native堆中来回复制数据。