JVM运行时数据区

总述

堆、方法区(元空间) 主要用来存放数据,是线程共享的。
程序计数器、本地方法栈、虚拟机栈 、是运行程序的,是线程私有的。
在这里插入图片描述

程序计数器

jvm中的程序计数器不是cpu中的寄存器,可以理解为计数器。
是一块非常小的内存空间,运行速度是最快的,不会出现内存溢出情况。

作用:
记录当前线程中的方法执行的位置,以便于cpu在切换执行时,记录程序执行的为位置。

在运行时数据区中唯一一个不会出现内存溢出的区域。

本地方法栈

当我们在程序中调用本地方法时,会将本地方法加载到本地方法栈中执行。
也是线程私有的,如果空间不够,也会出现栈溢出错误 。 hashCode();

虚拟机栈

背景:java为了移植性好(跨平台)所以将运行程序的设计架构为栈结构运行,而不是依赖于cpu的寄存器架构。

栈是运行时的单元(加载方法运行)

而堆是存储的单位(存储对象的)

作用运行方法,一个方法就是一个栈帧,栈帧中包含(局部变量(基本类型,引用地址)方法地址,返回地址)

栈中的操作 : 入栈, 出栈

栈中异常 StackOverflowError :
线程请求的栈深度大于虚拟机所允许的深度。递归调用方法次数过多。

栈中存储方法运行时需要的数据

栈的运行原理:

第一个方法被加载,入栈,在方法中调用了其他方法,另一个方法入栈方法运行结束后出栈。

栈帧的结构:
局部变量表 :方法参数,定义的局部变量,基本值类型直接存值,引用类型存地址。
操作数栈
动态链接
方法返回地址
在这里插入图片描述

Java堆

概述

堆是JVM内存中核心的区域,用来存储创建出来的对象,是线程共享的。

堆空间在jvm启动时被创建,大小可以设置

物理上不是连续的,逻辑上是连续的空间

堆中会发生垃圾回收

堆内存区域划分

堆内存划分为:
新生代(新生区)
老年代(老年区)
在这里插入图片描述

为什么要分区?

把不同生命周期的对象存储在不同的区域,这样不同的区域可以使用不同的垃圾回收算法,可以提高垃圾回收的效率。

对象在堆内存中的过程:

新建的对象存放在伊甸园区,第一次垃圾回收时,垃圾对象直接被回收掉,存活下来的对象,会把他存放在幸存者0/幸存者1.
再次垃圾回收时,把在幸存0区存活的对象,移动到幸存者1区,然后将幸存者0区清空,依次交替执行。
每次保证有一个幸存者区域是空的,内存是完整地。
当对象经过15次垃圾回收后,依旧存活的,将被移动到老年区(垃圾回收频率比较低)
在这里插入图片描述

 public static void main(String[] args) {
        List<Integer> list = new ArrayList();
        while(true){
            list.add(new Random().nextInt());
        }
    }

在这里插入图片描述

为什么是15次后,移入老年区?

因为在对象头中只有4个bit位的空间 1111, 只能表示最大值15

堆各区域的占比?

新生代 :占整堆的三分之一
新生代 中的 伊甸园区 幸存者0 幸存者1 占比是 8:1:1

堆空间的参数设置

一般所说的JVM优化,就是调整jvm相关各区的参数

-参数设置

分代收集思想Minor GC 、Major GC 、 Full GC

一般情况下收集新生代 Minor GC / Yong GC
老年代 会触发Major GC / Old GC
整堆收集Full GC

整堆收集触发的条件:

System .gc(); 时
老年区空间不足
方法区空间不足

开发期间尽量避免整堆收集(在垃圾回收时,会STW top-the-word 回收时停止其他线程运行)

TLAB机制

TLAB线程本地分配缓存区

在多线程情况下,可以在堆空间中通过 -XX:UseTLAB 设置,在堆空间中为线程开辟一块空间,用来存储线程中产生的一些对象,避免空间竞争,提高分配效率

字符串常量池位置

jdk7之前,将字符串常量池位置在方法区(永久代)中存储,
jdk8之后,方法区又称为元空间

jdk8之后,将字符串常量池的位置放到了堆空间,因为方法区只有触发Full GC 时才会回收。

因为程序中大量的需要使用字符串,所以将字符串常量池的位置改变到了堆中,可以及时回收无效的字符串常量

方法区

概述

方法区也是一块内存空间,逻辑上属于堆,为了区分,称为元空间(jdk8之后)
主要用来存储类的信息
在jvm启动时创建,大小可以分配
如果加载的类太多,也会报内存溢出错误
是线程共享的

参数设置

方法区的大小可以通过 -XX:MetaspaceSize 设置
方法区在window中默认大小是21MB
如果到达21MB会触发Full GC
可以将其值设置的大一些,减少Full GC的触发

类的信息卸载(回收条件)

方法区中主要回收运行时常量池,类的信息
类的信息卸载(回收)条件是比较苛刻的。
满足3个条件:
1、该类以及子类的对象没有被引用
2、该类的类加载器被卸载
3、该类的Class对象也没有被引用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值