没有合适的资源?快使用搜索试试~ 我知道了~
第25讲谈谈JVM内存区域的划分,哪些区域可能发生OutOfMemoryError1
需积分: 0 1 下载量 134 浏览量
2022-08-03
20:42:47
上传
评论
收藏 787KB PDF 举报
温馨提示
试读
11页
第二,Java 虚拟机栈(Java Virtual Machine Stack),早期也叫 Java 栈 第三,堆(Heap),它是 Java 内存管理的核心区
资源详情
资源评论
资源推荐
极客时间 | Java核心技术36讲
https://time.geekbang.org/column/article/10192[2018/7/19 14:42:36]
第25
讲
|
谈谈
JVM内存区域的划分,哪些区域可
能
发
生OutOfMemoryError?
2018-07-03 杨晓峰
第
25
讲
|
谈谈
JVM
内存区域的划分,哪些区域可能
发
生
OutOfMemoryError?
朗读人:黄洲君 10′42′′ | 4.90M
今天,我将从内存管理的角度,进一步探索 Java 虚拟机(JVM)。垃圾收集机制为我们打理了很
多繁琐的工作,大大提高了开发的效率,但是,垃圾收集也不是万能的,懂得 JVM 内部的内存结
构、工作机制,是设计高扩展性应用和诊断运行时问题的基础,也是 Java 工程师进阶的必备能
力。
今天我要问你的问题是,谈谈 JVM 内存区域的划分,哪些区域可能发生 OutOfMemoryError?
典型回答
通常可以把 JVM 内存区域分为下面几个方面,其中,有的区域是以线程为单位,而有的区域则是
整个 JVM 进程唯一的。
首先,程序计数器(PC,Program Counter Register)。在 JVM 规范中,每个线程都有它自己的
程序计数器,并且任何时间一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器
会存储当前线程正在执行的 Java 方法的 JVM 指令地址;或者,如果是在执行本地方法,则是未指
定值(undefined)。
极客时间 | Java核心技术36讲
https://time.geekbang.org/column/article/10192[2018/7/19 14:42:36]
第二,Java 虚拟机栈(Java Virtual Machine Stack),早期也叫 Java 栈。每个线程在创建时都
会创建一个虚拟机栈,其内部保存一个个的栈帧(Stack Frame),对应着一次次的 Java 方法调
用。
前面谈程序计数器时,提到了当前方法;同理,在一个时间点,对应的只会有一个活动的栈帧,通
常叫作当前帧,方法所在的类叫作当前类。如果在该方法中调用了其他方法,对应的新的栈帧会被
创建出来,成为新的当前帧,一直到它返回结果或者执行结束。JVM 直接对 Java 栈的操作只有两
个,就是对栈帧的压栈和出栈。
栈帧中存储着局部变量表、操作数(operand)栈、动态链接、方法正常退出或者异常退出的定义
等。
第三,堆(Heap),它是 Java 内存管理的核心区域,用来放置 Java 对象实例,几乎所有创建的
Java 对象实例都是被直接分配在堆上。堆被所有的线程共享,在虚拟机启动时,我们指定
的“Xmx”之类参数就是用来指定最大堆空间等指标。
理所当然,堆也是垃圾收集器重点照顾的区域,所以堆内空间还会被不同的垃圾收集器进行进一步
的细分,最有名的就是新生代、老年代的划分。
第四,方法区(Method Area)。这也是所有线程共享的一块内存区域,用于存储所谓的元
(Meta)数据,例如类结构信息,以及对应的运行时常量池、字段、方法代码等。
由于早期的 Hotspot JVM 实现,很多人习惯于将方法区称为永久代(Permanent
Generation)。Oracle JDK 8 中将永久代移除,同时增加了元数据区(Metaspace)。
第五,运行时常量池(Run-Time Constant Pool),这是方法区的一部分。如果仔细分析过反编
译的类文件结构,你能看到版本号、字段、方法、超类、接口等各种信息,还有一项信息就是常量
池。Java 的常量池可以存放各种常量信息,不管是编译期生成的各种字面量,还是需要在运行时决
定的符号引用,所以它比一般语言的符号表存储的信息更加宽泛。
第六,本地方法栈(Native Method Stack)。它和 Java 虚拟机栈是非常相似的,支持对本地方
法的调用,也是每个线程都会创建一个。在 Oracle Hotspot JVM 中,本地方法栈和 Java 虚拟机
栈是在同一块儿区域,这完全取决于技术实现的决定,并未在规范中强制。
考点分析
这是个 JVM 领域的基础题目,我给出的答案依据的是JVM 规范中运行时数据区定义,这也和大多
数书籍和资料解读的角度类似。
JVM 内部的概念庞杂,对于初学者比较晦涩,我的建议是在工作之余,还是要去阅读经典书籍,比
如我推荐过多次的《深入理解 Java 虚拟机》。
极客时间 | Java核心技术36讲
https://time.geekbang.org/column/article/10192[2018/7/19 14:42:36]
今天这一讲作为 Java 虚拟机内存管理的开篇,我会侧重于:
分析广义上的 JVM 内存结构或者说 Java 进程内存结构。
谈到 Java 内存模型,不可避免的要涉及 OutOfMemory(OOM)问题,那么在 Java 里面存在
哪些种 OOM 的可能性,分别对应哪个内存区域的异常状况呢?
注意,具体 JVM 的内存结构,其实取决于其实现,不同厂商的 JVM,或者同一厂商发布的不同版
本,都有可能存在一定差异。我在下面的分析中,还会介绍 Oracle Hotspot JVM 的部分设计变
化。
知
识扩
展
首先,为了让你有个更加直观、清晰的印象,我画了一个简单的内存结构图,里面展示了我前面提
到的堆、线程栈等区域,并从数量上说明了什么是线程私有,例如,程序计数器、Java 栈等,以及
什么是 Java 进程唯一。另外,还额外划分出了直接内存等区域。
这张图反映了实际中 Java 进程内存占用,与规范中定义的 JVM 运行时数据区之间的差别,它可以
看作是运行时数据区的一个超集。毕竟理论上的视角和现实中的视角是有区别的,规范侧重的是通
用的、无差别的部分,而对于应用开发者来说,只要是 Java 进程在运行时会占用,都会影响到我
们的工程实践。
我这里简要介绍两点区别:
剩余10页未读,继续阅读
爱设计的唐老鸭
- 粉丝: 19
- 资源: 291
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0