JVM内存模型简述

一丶线程私有:

  1. 程序计数器:

    • 可以看做是线程执行字节码的行号指示器

    • 如果正在执行java方法,这个计数器记录的是正在执行的虚拟机的字节码指令的地址

    • 如果正在执行native方法,这个计数器记录的值为空(undefined)

    • 唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域

  2. Java虚拟机栈

    • 描述的是Java方法执行的内存模型

    • 每个方法执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出入口等信息

    • 如果线程请求栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常

    • 如果虚拟机栈在扩展的过程中无法申请到足够的内存,就会抛出OutOfMemory异常

  3. 本地方法栈

    • 与虚拟机栈相同,只不过是为虚拟机使用到的Native方法服务。

二丶线程共享

  1. Java堆

    • 所有对象实例以及数组都要在堆上进行分配(并不是那么绝对)

    • -Xmx -Xms

    • 堆中没有内存完成实例分配,并且堆也无法扩展时,就会抛出OutOfMemoryError异常

  2. 方法区(永久代)

    • 存储加载的类信息、常量、静态常量、即时编译器编译后的代码数据

    • Java7及之前的版本:-XX:PermanSize Java8及之后的版本:-XX:MetaspaceSize

    • 当方法区没法满足内存分配需求时,将抛出OutOfMemoryError异常

  3. 运行时常量池

    • 是方法区的一部分

    • 存储编译期的生成的各种字面量与符号引用,运行时也会将新的常量放入池中

    • 常量池是方法区的一部分,当常量池无法再申请到内存时就会抛出OutOfMemoryError

  4. 直接内存

    • 不是虚拟机运行时数据区的一部分,也不是虚拟机规范中定义的区域

    • NIO引入了一种基于通道与缓冲区的I/O方式,使用native函数库直接分配堆外内存,通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作

    • 动态扩展时会出现OutOfMemoryError异常

三丶Java版本迭代导致的内存区域发生的变化

在Java7之前,HotSpot虚拟机中将GC分代收集扩展到了方法区,使用永久代来实现了方法区。这个区域的内存回收目标主要是针对常量池的回收和对类型的卸载。但是在之后的HotSpot虚拟机实现中,逐渐开始将方法区从永久代移除。Java7中已经将运行时常量池从永久代移除,在Java 堆(Heap)中开辟了一块区域存放运行时常量池。而在Java8中,已经彻底没有了永久代,将方法区直接放在一个与堆不相连的本地内存区域,这个区域被叫做元空间。

image.png
image.png
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 文章转自 http://blog.csdn.net/u012152619/article/details/4696...
    云狗狗狗狗狗阅读 676评论 1 4
  • 内存溢出和内存泄漏的区别 内存溢出:out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,...
    Aimerwhy阅读 808评论 0 1
  • 我们知道,计算机CPU和内存的交互是最频繁的,内存是我们的高速缓存区,用户磁盘和CPU的交互,而CPU运转速度越来...
    join_a922阅读 311评论 0 0
  • 这篇文章是我之前翻阅了不少的书籍以及从网络上收集的一些资料的整理,因此不免有一些不准确的地方,同时不同JDK版本的...
    高广超阅读 16,061评论 3 83
  • Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,总共包括以下几个运行时数...
    _云起阅读 401评论 0 0

友情链接更多精彩内容