jvm学习的核心(三)---运行时数据区详解(2)
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
文章目录
1.堆heap
1.1 堆的概述
- 一个JVM实例
只存在一个堆内存
堆也是Java内存管理的核心区域。. Java堆区在JVM启动的时候即被创建其空间大小也就确定了。是JVM
管理的最大
一块内存空间。 - 堆内存的大小是可以调节的。
《Java虚拟机规范》规定堆可以处于物理上不连续
的内存空间中但在逻辑上它应该被视为连续
的。 - 所有的线程共享Java堆在这里还可以划分线程
私有的缓冲区
Thread
Local Allocation Buffer,TLAB
)。
1.2 堆的内部结构
引用自https://blog.csdn.net/lovely_girl1126/article/details/106806879
堆的内部结构主要包括
1.新生区伊甸园区幸存者0区幸存者1区
2.老年区一般是最大的区
3:元空间jdk1.7及以前为永久代元空间和永久代尽管上在逻辑上是堆的一部分但实际位置并不在堆内
1.3 堆分代垃圾回收流程的简单理解
1.新生对象在伊甸园区内存足够的情况下一般会分配到伊甸园区。
2.新生区在会进行Minor GC
。
3.minor Gc一般在伊甸园内存不够时进行当该区进行gc的时候存活对象会放入幸存者0区于此同时会对另一个幸存者区年龄增加存活判断判断是否进入养老区或者被回收于此同时将该幸存者区对象移动到另一个幸存者区中一个幸存者区置空置空的区叫做幸存者0区不置空的区为幸存者1区。
4.幸存者区的回收不单独进行
一般伴随伊甸园区的回收进行。
5.一般将年龄阈值
或者过半对象数量年龄
作为进入养老区的条件。
6.养老区的gc叫major Gc
不过只有CMS GC
会单独回收养老区Full Gc
一般会包括所有的堆空间和方法区
7.对象如果过大某区不能满足则直接放置到能放置的下面的区。
2.方法区 Method Area
2.1 HotSpot
方法区的演进
1.在jdk7及以前习惯上把方法区称为永久代。jdk8开始使用元空间取代了永久代
2.本质上方法区和永久代并不等价。仅是对hotspot而言的。《Java虚拟机规范》对如何实现方法区不做统一要求。例如:BEA JRockit/ IBMJ9中不存在永久代的概念。
3.永久代相对来说容易oom。超过永久代空间的上限
2.2方法区的内部结构
《深入理解Java 虚拟机》书中对方法区(Method Area存储内容描述如下
它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等
。
2.3.1 常量池和运行时常量池概念区别
1.常量池在编译时确定在字节码文件中已经体现
2.运行时常量池是方法区的一部分
- 运行时常量池 Runtime Constant Poo1是方法区的一部分。
- 常量池表(Constant Pool Table是class文件的一部分用于存放编译期生成的各种字面量与符号引用这部分内容将在类加载后存放到方法区的运行时常量池中。运行时常量池在加载类和接口到虚拟机后就会创建对应的运行时常量池。
- JVM为每个已加载的类型类或接口都维护一个常量池。池中的数据项像数组项一样是通过索引访问的。
- 运行时常量池中包含多种不同的常量包括编译期就已经明确的数值字面量也包括到运行期解析后才能够获得的方法或者字段引用。此时不再是常量池中的符号地址了这里换为真实地址。
- 运行时常量池相对于class文件常量池的另一重要特征是:具备动态性。
运行时常量池类似于传统编程语言中的符号表(symbol table)但是它所包含的数据却比符号表要更加丰富一些。 - 当创建类或接口的运行时常量池时如果构造运行时常量池所需的内存空间超过了方法区所能提供的最大值则JVM会抛outofMemoryError异常。