一、Java运行时内存
- 方法区(公有):用于存储被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。会出现OutOfMemoryError异常,如使用String.intern()导致方法区泄漏。
其中包含常量池:用户存放编译器生成的各种字面量和符号引用。
- 堆(公有):JVM所管理的内存中最大的一块。唯一目的就是存放实例对象,即new创建的对象,几乎所有的对象存放都在这里分配。Java堆是垃圾收集器的主要区域,被称为“GC堆”。会出现OutOfMemoryError异常
- 虚拟机栈(线程私有):每个方法在执行时都会创建一个栈帧,用户存储局部变量表、操作数栈、动态链接、方法出口信息。每个方法从调用直到完成的过程,就对应着一个栈帧在栈中入栈和出栈的过程。会出现的异常:OutOfMemoryError和StackOverflowError
- 本地方法栈(线程私有):与虚拟机栈发挥的作用类似。它们之间的区别不过是虚拟机栈为虚拟机执行Java方法,而本地方法栈为虚拟机使用到Native方法服务。会出现的异常:OutOfMemoryError和StackOverflowError
- 程序计数器(线程私有):一块较小的内存,当前线程锁所执行的字节码的行号指示器。字节码解释器工作时,就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。
二、Java内存模型
Java内存模型的目的
屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果。
Java内存模型规定所有的变量都存储在主内存中。每条线程中还有自己的工作内存,线程的工作内存中保存了被该线程所使用到的变量(这些变量是主内存对应变量的副本)。线程对变量的所有操作(读取、赋值)都必须在工作内存中进行。不同线程之间无法直接访问对方的工作内存的变量(类似工作内存线程私有)。线程间变量值的传递需要通过主内存来完成。
(图片来源于:github.com/LRH1993/and…)
