JVM调优 知识体系学习 二

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内存分配参数

在写中
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值