目录
JVM调优 知识体系学习 一
https://blog.csdn.net/baidu_37313657/article/details/107208135
Java内存分配
JVM的简化架构
运行时数据区
- PC寄存器、Java虚拟机栈、Java堆、方法区、运行时常量池、本地方法栈等。
PC寄存器(Program Counter)
- 每个线程拥有一个PC寄存器,是线程私有的,用来存储指向下一条指令的地址。
- 在创建线程的时候,创建相应的PC寄存器。
- 执行本地方式时,PC寄存器的值为undefined。
- 是一块较小的内存空间,是唯一一个在JVM规范中没有规定OutOfMemoryError的内存区域。
Java栈
- 栈由一系列帧(Frame)组成(因此Java栈也叫做帧栈),是线程私有的。(栈是数据结构,帧也是数据结构,其实就是栈中存放的帧)
- 帧用来保存一个方法的局部变量,操作数栈(Java没有寄存器,所有参数传递使用操作数栈)、常量池指针、动态链接、方法返回值等。
- 每一次方法调用创建一个帧,并压栈,退出方法的时候,修改栈顶指针就可以把栈帧中的内容销毁。
- 局部变量表存放了编译期可知的各种基本数据类型和引用类型,每个slot存放32位的数据,long、double占两个槽位。
- 栈的优点:存取速度比堆快,仅次于寄存器。
- 栈的缺点:存在栈中的数据大小、生存期是在编译期决定的,缺乏灵活性。
Java堆
- 用来存放应用系统创建的对象和数组,所有线程共享java堆。
- GC主要就管理堆空间,对分代GC来说,堆也是分代的。
- 堆的优点:运行期动态分配内存大小,自动进行垃圾回收。
- 堆的缺点:效率相对较慢。
方法区
- 方法区是线程共享的,通常用来保存装载的类的结构信息。
- 通常和元空间关联在一起,但具体的跟JVM实现和版本有关。
- JVM规范把方法区描述为堆的一个逻辑部分,但它有一个别名为Non-heap(非堆),应是为了与Java堆区分开。
运行时常量池
- 是Class文件中每个类或接口的常量池表,在运行期间的表示形式,通常包括:类的版本、字段、方法、接口等信息。
- 在方法区中分配。
- 通常在加载类和接口到JVM后,就创建相应的运行时常量池。
本地方法栈
- 在JVM中用来支持native方法执行的栈就是本地方法栈。
栈、堆、方法区交换关系
Java堆内存概述
- Java堆用来存放应用系统创建的对象和数组,所有线程共享Java堆。
- Java堆是在运行期动态分配内存大小,自动进行垃圾回收。
- Java垃圾回收(GC)主要就是回收堆内存,对分代GC来说,堆也是分代的。
Java堆的结构
上面是新生代,下面是老年带,新生代Eden space是存放新创建的对象,from和to是存活区,新生代是由 Eden space和from space(存活区)组成,To Space 当垃圾回收不完或虚拟机判断说这个东西需要存下来的时候,则转入老年代。Survicor ratio是设置存活区和eden区的一个比例.
- 新生代用来放新分配的对象;新生代中经过垃圾回收,没有回收掉的对象,被复制到老年代。
- 老年代存储对象比新生代存储对象的年龄大得多。
- 老年代存储一些大对象。
- 整个堆大小 = 新生代 + 老年代。
- 新生代 = Eden + 存活区。
- 从前的持久代,用来存放Class、Method等元信息的区域,从JDK8开始去掉了,取而代之的是元空间(MetaSpace),元空间并不在虚拟机里面,而是直接使用本地内存。
对象的内存布局(就是new出来的)
- 对象在内存中存储的布局(这里以HotSpot虚拟机为例来说明),分为:对象头、实例数据和对齐填充。
- 对象头,包含两个部分:
1.Mark Word:存储对象自身的运行数据,如 HashCode、GC分代年龄、锁状态标志等。
2.类型指针:对象指向它的类元数据的指针。 - 实时数据: 真正存放对象实例数据的地方。
- 对齐填充:这部分不一定存在,也没有什么特别含义,仅仅是占位符,因为HotSpot要求对象起始地址都是8字节的整数倍,如果不是,就对齐。
对象的访问定位
- 对象的访问定位,在JVM规范中只规定了reference类型是一个指向对象的引用,但没有规定这个引用具体如何去定位、访问堆中对象的具体位置。
- 因此对象的访问方式取决于JVM的实现,目前主流的有:使用句柄或者使用指针两种方式。
- 使用句柄:Java堆中会规划分出一块内存来做为句柄池,reference中存储句柄的地址,句柄中存储对象的实例数据和类元数据的地址,如图:
- 使用指针:Java堆中会存放访问类元数据的地址,reference存储的就直接是对象的地址,如图:
HotSpot 就是使用指针方式。
JVM调优 知识体系学习 三
下一章讲
Java内存分配参数
在写中