JVM 理解整理

目录

运行时数据区域

方法区

虚拟机栈

本地方法栈

程序计数器

运行时常量池

直接内存

hotspot虚拟机

创建对象

对象访问定位

垃圾收集器

对象存活判断

垃圾回收的算法

垃圾收集器

内存分配和回收策略


记录自己在学习jvm中总结的有用内容:

JVM在执行程序时将内存分为若干数据区域

运行时数据区域

  • 方法区

线程共享区域

存放JVM加载的类常量等

当无法满足内存分配的时候也会抛出OutOfMemoryError

  1. 运行时常量池(java 并不是要求常量一定要编译才能产生,运行时的常量放入常量池中)

  2. 直接内存

  3. 只是在hotspot虚拟机中可以称为永久代,在新版本的jdk中已经放弃永久代用Native Memory来规划,将字符串常量池移出了永久代

  • 虚拟机栈

作为每隔线程所私有的,一般存放的是局部变量例如基本数据类型,主要为执行的java方法服务,在这里会有两种异常stackOverflowError和OutOfMemoryError,第一个是出现在线程请求的深度大于JVM允许的深度,第二是在动态扩展时请求内存未分配到

  • 本地方法栈

主要是为我们的Native原生方法服务的地方,同时也会同虚拟机栈一样抛出相同异常

线程共享区域,简单来说就是放实例对象的地方

简单来说就是新建对象new出来存放地方,也是主要GC回收区域

如果新对象没有在堆中完成实例分配,堆无法扩展就会出现OutOfMemoryError

可以分为新生代和老年代

  • 程序计数器

是用来作为记录每个线程字节码行号的指示器,jvm通过这个计数器来确定需要执行的下一个步骤

也是jvm中唯一一个未规定OutOfMemoryError的地方

  • 运行时常量池

是方法区的一部分存放字面量和符号引用,JVM中常量不一定要编译才产生,在运行时也可以放入常量池,受到内存限制,无法申请到内存时OutOfMemoryError

  • 直接内存

NIO类可以直接使用Native函数库分配堆外的内存

hotspot虚拟机

  • 创建对象

首先会去检查参数是否在常量池中能找到,再检查对象代表引用的类是否已加载,解析初始化过,若没有则先执行类加载

对象再分配内存时:①指针碰撞(内存规整,用过的内存放在一边,另外一边是空闲的内存,内存分配仅分配指针)②空闲列表(内存不规整的时候,需要在内存中单独维护一个表)

使用哪种分配内存取决于GC垃圾回收是否带有压缩整理功能,解决并发安全问题(①虚拟机采用CAS上配置失败重试保证原子性②内存分配按照线程分配不同空间)

  • 对象访问定位

需要通过栈上的reference来操作堆上的具体对象,通过方式有句柄方式和直接指针

第一种就需要内存中的句柄池,优点是对象移动后无需修改reference数据,只用修改指针,第二种reference中就放置的对象地址访问速度快

  • 垃圾收集器

  1. 对象存活判断

有两种算法:引用计数法和可达性分析算法,第一种简单理解就是对象的引用有一个计数器,每次使用和失效就做对应的加减,存在问题就是出现对象之间相互引用的时候导致计数都不是0,优点是效率高

第二种存在一个GC ROOT的根节点作为初始对象,从此往下搜索通过引用链是否可达判断存活,在算法判断存活后会进入缓存阶段,一般判断死亡至少经过两次标记。

在jvm中新生代的回收效率远远大于永久代的回收效率,永久代一般回收废弃常量(只要没有引用)和类(①该类的在堆中所有实例不存在②类加载被回收③Class对象没有被引用,无法反射获取Class)

  1. 垃圾回收的算法

①标记清除算法(先标记后清除效率低,回收后存在大量的内存碎片)

②复制算法(每次将存活对象复制在内存空间,然后整理原空间)一般新生代采用第二种,但是在一些场景下需要进入老年代的对象过多Survivor空间不够的时候需要老年代分配担保

③标记整理算法(根据老年代的特点若复制算法,效率低,若想减少50%的内存就需要担保)

④分代收集算法(在堆中分成老年代和新生代,新生代更新换代快,大部分都直接被回收,适合复制算法,老年代存活率高一般使用标记整理或标记清除)

⑤hotspot算法中:可达性分析从GC ROOT根对象判断可达当对象过多的时候会出现,随之而来的GC停顿,使用OopMap的数据结构来记录哪些地方存在引用用于当系统停顿时。通过OopMap就可以快速的完成GC ROOT枚举,但是hotspot中没有为每条指令都生成的了OopMap,而是在GC停顿时在安全点生成。所以在进入GC时安全点完美解决了问题,但是在不执行的程序例如sleep或者锁住的状态,这个时候不可能呢长时间等待,则需要安全区(指在一段代码片段中,引用关系不变化,这个区域中GC是安全的)线程执行到安全区先标记一次当要离开安全区域的时候,先检查是否完成了对GC ROOT的枚举,没完成线程等待

  1. 垃圾收集器

 

  1. 内存分配和回收策略

 

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值