《深入理解 Java 虚拟机》学习笔记 Day1(运行时数据区域:程序计数器、Java 虚拟机栈、本地方法栈)

学习内容:第2章 - Java 内存区域与内存溢出异常

相比C、C++等语言,开发 Java 程序时在虚拟机自动内存管理机制的帮助下,不需要手动对对象生命周期进行维护。但如果出现内存泄漏或者内存溢出方面的问题,很难排查错误、修正问题。

-> 学习内容:了解虚拟机如何控制内存
-> 学习目的:掌握排查、修正内存泄漏和溢出方面的问题的能力

思考:通过对中间层对复杂操作进行封装是我们常考虑的操作,相比与白盒操作,这降低了系统的上手难度,一定程度上降低了大型系统的开发难度。与之对应的可能就是可靠性上的降低,这一点需要进行斟酌。

运行时数据区域

按照 Java 虚拟机规范,Java 虚拟机管理的内存将会包含以下几个运行时数据区域:

  • 程序计数器(Program Counter Register)
  • Java 虚拟机栈(Java Virtual Machine Stack)
  • 本地方法栈(Native Method Stacks)
  • Java 堆(Java Heap)
  • 方法区(Method Area)
    在这里插入图片描述

程序计数器(Program Counter Register)

特点:

  • 是线程私有的内存区域,每个线程都有一个独立的程序计数器,互不影响
  • 在虚拟机规范中,该区域是唯一没有规定任何 OutOfMemoryError 情况的区域

工作内容:
字节码解释器工作时通过改变计数器的值来选取下一条需要执行的字节码指令。如果线程执行的是一个 Java 方法,计数器记录的是正在执行的虚拟机字节码指令的地址。如果正在执行的是本地(Native)方法,计数器的值为空

作用:
是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复这些基础功能都依赖它来完成

Java 虚拟机栈(Java Virtual Machine Stack)

特点:

  • 线程私有
  • 生命周期与线程相同

工作内容:
在每个方法执行的时候,虚拟机都会同步创建一个栈帧(Stack Frame)来存储局部变量表、操作数栈、动态连接、方法出口等信息。方法调用直至执行完毕,对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

作用:
描述了 Java 方法执行的线程内存模型

局部变量表

存放了编译期可知的各种 Java 虚拟机基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型,不是对象本身,可能是指向对象地址的引用指针,也可能是其他与此对象相关的位置)和 returnAddress 类型(指向一条字节码指令的地址)
这些数据类型在局部变量表中以局部变量槽(Slot)来表示,64 位长度的 long 和 double 会占用两个 Slot,其它类型只占用一个。局部变量表所需内存空间在编译期完成分配,方法运行期间不会改变其大小。而虚拟机真正使用多大内存空间来实现一个变量槽,也完全由虚拟机自行决定。

异常状况:

  • 如果线程请求的栈深度大于虚拟机所允许的深度,就会抛出 StackOverflowError 异常。
  • 如果 Java 虚拟机栈容量可以动态扩展,当栈扩展时无法申请到足够的内存,就会抛出 OutOfMemoryError 异常

HotSpot 虚拟机的栈容量不可以动态扩展,Classic 虚拟机可以。所以在 HotSpot 虚拟机上不会因为虚拟机栈无法扩展而导致 OutOfMemoryError 异常。但是如果线程申请时就失败,仍然会出现 OOM 异常。

本地方法栈(Native Method Stacks)

特点:

  • 与虚拟机栈发挥的作用非常相似,其区别虚拟机栈为虚拟机执行 Java 方法(字节码)服务,而本地方法栈则是为虚拟机用到的本地(Native)方法服务
  • 本地方法栈中方法使用的语言、使用方式与数据结构没有任何强制规定,具体虚拟机可以根据需求进行自由实现,像 HotSpot 就直接把本地方法栈和虚拟机栈合二为一

异常状况:

  • 与虚拟机栈一样,本地方法栈也会在栈深度溢出或者栈扩展失败时分别抛出 StackOverflowErrorOutOfMemoryError 异常
  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值