Java内存模型

Java内存模型图

Java内存模型

程序计数器

  1. 是一块较小的内存空间, 用来指示当前线程正在执行的Java字节码位置. 如果正在执行Java方法, 则计数器记录的是当前字节码的地址, 如果正在执行本地方法, 则计数器为空.
  2. 线程私有, 所以不会出现线程安全问题.
  3. 此区域是唯一一个在<<Java虚拟机规范>>中没有规定任何OutOfMemoryError的区域

虚拟机栈

  1. 生命周期和线程保持一致, 每个线程都会分配一块栈空间, 这也解释了为啥不要频繁地创建线程的原因, 而是尽量复用线程, 创建线程的过程牵涉到虚拟机栈的内存分配, 空间不足则会导致OutOfMemoryError, 销毁线程又涉及到栈内存的回收 , 出现不必要的垃圾回收.
  2. 栈空间是每个线程私有的, 执行的方法区的代码大多数情况下是线程安全的(代码逃逸除外.
  3. 当执行Java代码的时候, 会同步创建一个栈帧, 用来存储局部变量表, 操作数栈, 方法出口等信息
  4. 如果线程请求的栈深度大于Java虚拟机规范的深度, 抛出*Error. 如果Java虚拟机可以动态扩展, 当栈无法申请到足够的内存时, 出现OOM.

本地方法栈

  1. 与虚拟机栈类似, 只不过是执行本地方法.
  2. 线程私有.
  3. 和虚拟机栈一样, 同样会出现OOM和SOF.

  1. 虚拟机所管理的内存中最大的一块, 在虚拟机启动时创建, 所有的对象实例数组都在堆上创建.
  2. 大小一般是可扩展的.如-Xmx 1000m , 表示最大堆内存分配为1000MB, -Xms 10m 表示最小堆内存为10MB
  3. 当堆中没有内存完成分配时, 会出现OOM

方法区

  1. 存放已经被虚拟机加载的类型信息, 常量, 静态变量, 热点代码
  2. 线程共享, 注意线程安全问题
  3. jdk6以后就开始使用本地内存来实现方法区
  4. 当无法申请到合适的内存时, 会出现OOM

运行时常量池

  1. 存放class文件中的常量池的内容, 包含编译时期生成的各种字面量和符号引用
  2. 运行期间新的常量, 如String的intern方法

直接内存

  1. 不是Java运行时数据区的一部分, Java程序仍可以使用这部分内存
  2. 内存区域总和超过物理内存大小时, 会出现OOM.
上一篇:OOM排除与JVM调优


下一篇:百度二面:一个线程OOM了,其它线程还能运行吗?