JVM内存
最后一次更新时间:Tuesday, July 28th 2020, PM
Java内存(运行时数据区)
在Java1.8之前长这样:
在Java1.8之后长这样:
二者最大的区别即图中蓝框所示的部分。在Java1.8之后,“方法区”改名为“元空间”,且放入直接内存(系统内存)中,不再属于JVM内存,相关介绍在本文方法区部分有讲。大部分面试是以Java1.8之前的版本来进行考量。
接下来我们分别来介绍JVM内存组成部分。
Java虚拟机栈(VM Stack)
虚拟机栈是为Java字节码相关功能服务的。(我的理解是服务于Java代码相关部分)。
虚拟机栈结构包括
- 局部变量表
- 操作数栈
- 动态链接
- 方法出口
其中,局部变量表 负责存放各种数据类型(int,byte,char … )以及对象的引用(reference类型)
虚拟机栈的生命周期由其线程生命周期决定(很好理解,虚拟机栈就是属于某个线程)。
虚拟机栈的两种异常:
1.StackOverFlowError:Stack不支持动态拓展,Stack 用完了
2.OutOfMemoryError :Stack 支持动态拓展,Memory用完了
本地方法栈
本地方法栈只为Native方法服务(Native方法:非Java代码实现的方法)。
本地方法栈的结构、生命周期、异常与虚拟机栈类似,此处不赘述。
堆(Heap)
堆是JVM中最大的一块内存,只存放 对象实例 以及 数组。
是垃圾收集器管理的主要区域,因此也被称为“GC堆”
从垃圾回收的角度看,堆可以划分为 新生代 和 老年代(至于我们常说的 永久代 并不属于堆内存)。新生代可继续划分为Eden区和Survivor区。Survivor区可继续划分为S0区和S1区。相关内容我会在Java垃圾回收篇详说,此处留白。
方法区
方法区用来存储 类信息、常量、静态变量、编译后的代码 等数据。
实现方法区的内存也被称为 永久代(PermGen)
Java1.8之后,方法区变为元空间(MetaSpace),使用直接内存。这样做的好处是:
不受JVM内存限制,不会触发OutOfMemoryError
常量池 (方法区的一部分)
常量池的结构如下:
- 字面量
- 文本字符串
- final修饰的常量
- 基本数据类型的值
- 其它
- 符号引用
- 类和结构的完全限定名
- 字段名称 和 描述符
- 方法名称 和 描述符
除特别声明外,本站所有文章均采用 CC BY-SA 4.0 协议 ,转载请注明出处!