前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JVM-1. Java运行时内存

JVM-1. Java运行时内存

作者头像
悠扬前奏
发布2019-05-29 17:16:22
8260
发布2019-05-29 17:16:22
举报
文章被收录于专栏:悠扬前奏的博客

Java虚拟机运行时数据区

方法区(Method Area)和堆(Heap)是所有下次呢很难过共享的数据区 虚拟机栈(VM Stack),本地方法栈(Native Method Stack)和程序计数器(Program Counter Register)是线程隔离的数据区。

1. 程序计数器(Program Counter Register)

  • 程序计数器是一块儿较小的内存空间,可以看做是当前线程执行的字节码的行号指示器。
  • 作用:字节码解释器通过改变计数器值来选取下一条需要执行的字节码指令,分支,循环,跳转,异常处理,线程恢复等基础功能都需要这个计数器。
  • 线程私有
  • 内容:如果线程执行的是一个Java方法,计数器记录的是正在执行虚拟机字节码指令的地址;如果执行的是Native方法,计数器为空(Undefined)
  • 这个内存没有规定任何OutOfMemoryError的情况。

2. Java虚拟机栈(Java Virtual Machine Stacks)

  • 特点:线程私有,生命周期和线程相同
  • 作用:描述了Java方法执行内存模型:每个方法在执行的同时都创建一个栈帧(Stack Frame)用于储存局部变量表操作数栈动态链接方法出口等信息。
    • 局部变量表:存放了编译期可知的各种基本数据类型(8中基本数据类型)、对象引用(reference类型),returnAddress类型(指向一条字节码指令的地址)。long和double占用两个局部变量空间(Slot),其余类型只占用一个。
    • 局部变量表的内存空间在编译期间完成分配,在进入一个方法时确认分配的局部变量空间大小,方法运行期间不会改变。
  • Java方法:每个Java方法从调用到执行完成,对应一个栈帧在虚拟机栈中入栈到出栈的过程。
  • Java虚拟机栈的两种异常:
    • 线程请求的栈深度大于虚拟机所允许的深度,抛出StackOverflowError异常
    • 虚拟机栈可以动态扩展,但是扩展时无法申请到足够的内存,抛出OutOfMemoryError异常

3. 本地方法栈(Native Method Stack)

  • 虚拟机栈为虚拟机执行Java方法(字节码)服务,而本地方法栈为虚拟机使用到的Native方法服务。
  • 虚拟机规范对本地方法栈中方法使用的语言,方式,数据结构都没有强制规定,由各虚拟机自由实现。
  • HotSpot虚拟机将本地方法栈和虚拟机栈合二为一
  • 本地方法栈也会抛出StockOverflowError和OutOfMemoryError异常。

4. Java 堆(Java Heap)

  • 线程共享
  • 在虚拟机启动时创建。
  • 其唯一目的就是存放内对象实例,所有的对象实例都在这里分配内存管。
  • 很多时候也被称为“GC堆(Garbage Collected Heap),因为它是垃圾收集器管理的主要区域。
    • 根据内存回收分为新生代和老年代
    • 新生代分为Eden,From Survivor空间,To Survivor空间。
  • 根据内存分配可以划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer TLAB)
  • 逻辑内存连续,物理内存可以不连续。
  • 通过-Xmx和-Xms配置大小
  • 当堆中没有内存完成实例分配,且堆无法扩展时,抛出OutOfMemoryError异常

5. 方法区(Method Area)

  • 线程共享
  • 存放了被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码
  • HotSpot虚拟机的GC分代收集扩展到了方法区,用“永久代”管理,因此有时被称为“永久代”
  • HotSpot用-XX:MaxPermSize设定永久代上限
  • 方法区无法满足内存分配需求,抛出OutOfMemoryError

6. 运行时常量池(Runtime Constant Pool)

  • 运行时常量池是方法区的一部分
  • 存放了编译期生成的字面量和符号引用,一般来说还存放了翻译出来的直接引用
  • 运行期间可以将新的常量放入运行时常量池
  • 常量池无法再申请到内存时抛出OutOfMemoryError异常

7. 直接内存(Direct Memory)

  • 直接内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,但是也被频繁使用
  • NIO类中的基于Channel和Buffer的I/O方式,使用Native函数库分配堆外内存,然后通过Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作
  • 如果各内存区域总和大于物理内存限制,动态扩展时出现OutOfMemoryError异常
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.04.05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 程序计数器(Program Counter Register)
  • 2. Java虚拟机栈(Java Virtual Machine Stacks)
  • 3. 本地方法栈(Native Method Stack)
  • 4. Java 堆(Java Heap)
  • 5. 方法区(Method Area)
  • 6. 运行时常量池(Runtime Constant Pool)
  • 7. 直接内存(Direct Memory)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档