JVM粗解


前言

什么是JVM


一、JVM是什么?

JVM的基本概念:对于java来说JVM是一个可运行java代码的假想计算机
JVM里面有一套 字节码指令集,一组寄存器,一个栈,一个垃圾回收器,堆和一个存储方法域。他运行在操作系统上,与硬件没有直接交互。

二、JVM的内存区域

1.思维导图

在这里插入图片描述

2.JVM运行时的内存

java的堆从GC角度分为新生代和老年代,比例是新生代1/3,老年代2/3。
因为频繁的创建对象所以新生代会频繁触发MinorGC进行(小范围GC回收)。
所以新生代分为 Eden区,ServivorFrom区,ServivorTo区。

  1. Eden区,对象刚创建的时候,如果对象很大的话会直接进入老年代。当Eden区内存不够就会触发一次GC,对新生代进行一次垃圾回收。

  2. ServivorFrom区,上一次GC的幸存者,会被当做这次GC的扫描者。(这里我的猜想是上次GC没有回收他但是会标记一下他,方便下次回收。)

  3. ServivorTo区,保留了一次MinorGC过程中的幸存者(这里你看的会有点懵,不着急慢慢往下看)

  4. MinorGC的垃圾回收算法

    MinorGC采用的是复制算法,首先把Eden区和ServivorFrom区中存活的对象复制到ServivorTo区
    去(如果有对象的年龄到达老年代的标准放入老年代),然后清空Eden和ServivorFrom中的对
    象,然后在把ServivorFrom区和ServivorTo区互换,原 ServicorTo 成为下一次 GC 时的
    ServicorFrom 区了。

什么是老年代

老年代主要存放生命周期长的内存对象。老年代的对象比较稳定,所以MajorGC不会频繁执
行,一般执行MajorGC的时候新生代都会执行一次MinorGC使新生代的对象晋升老年代,然
后导致老年代空间不足引发MajorGC。也有一种情况当无法为一个大对象分配一块连续空间
时候就会触发MajorGC清理出一块空间。

什么是永久代

内存永久保存的区域,主要存放class和元数据(1.8以后叫这个名字)的信息,class在被加
载的时候就会被存放入永久代,GC不会在主程序运行期间对永久代区域进行清理。所以这也导
致永久代区域会随着class的增多然后爆满,最终出现OOM异常。

3.JVM如何确定垃圾?

1.引用计数法
	java中引用和对象是有关联的(强弱软虚四种引用这里不做解释,大家可以百度),如果要操作对象必须要
	通过引用来操作,因此看这个对象有没有被引用,如果没有被引用哪这个对象就是可以被回收的的对象。
	这里会有 一个循环引用的问题,就是两个对象之间互相引用,但是没有其他的对象引用他们。这种情况下引
	用计数法就没有办法回收这两个对象了。

2.根可达法
	这个方法就是解决引用计数法里面的循环引用的问题。java通过一些列GC root根对象作为起点去搜索。如果
	GC root和一个对象之间不可达,那么这个对象就是不可达对象,注意!!!并不是不可达对象就要被回收,
	这里还要经历再次标记才能判断该不可达对象是否可以回收!
	第一次标记筛选
	筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize方法,或者finzlize方法已经
	被虚拟机调用过,虚拟机将这两种情况都视为“没有必要执行”,对象被回收。
	第二次标记
	如果这个对象被判定为有必要执行finalize()方法,那么这个对象会被放入一个F-Queue的队列中。
	finalize方法是对象逃脱死亡的最后一步,GC会对F-Queue队列中的对象进行二次小规模的回收,如果这个
	时候对象和GC root引用链上的任何一个对象挂钩的话那么就逃离了死亡。第二次标记的时候就会把这个对象
	移除“即将回收”的集合,如果没有逃脱那么就死翘翘了。

在这里插入图片描述


4.JVM的垃圾回收算法

  1. 标记清除算法
    最基础的垃圾回收算法,分为两步,第一步标记,标记出需要被回收的对象,然后执行第二步清除。
    这个算法缺点,造成内存碎片化严重,后续大对象没办法找到可以利用的空间。

  2. 复制算法
    为了解决标记清除算法的内存碎片化严重的问题,出现了复制算法。原理,把当前的内
    存区域一分为二,只使用一半,当那一半内存满了后把存活的对象复制进另外一半,然
    后把已使用的那一半内存清干净。就这样来回倒。
    缺点内存使用率只有原来的一般了,如果对象过多效率会很慢。

  3. 标记整理算法
    结合上面两个算法,先标记存活的对象然后把他们都整理到一端,然后把另一端的对象全部清理掉
    效率高,内存使用率高

  4. 分代收集法
    因为jvm会根据对象存活的生命周期划分不同的区域,分为新生代和老年代
    新生代会采用复制算法,因为新生代每次回收大部分对象,需要被复制的少而且新生代会被划分Eden区和两个Servivor区域,每次只使用Eden区和一块Servivor区域。
    老年代采用标记整理算法,老年代每次回收只回收少量对象。

  5. 分区收集法
    分区算法则将整个堆空间划分为连续的不同小区间, 每个小区间独立使用, 独立回收. 这样做的好处是可以控制一次回收多少个小区间 , 根据目标停顿时间, 每次合理地回收若干个小区间(而不是整个堆), 从而减少一次 GC 所产生的停顿

总结

上文就是对于JVM的一些整理,欢迎大家关注我的公众号,开源开拓。
欢迎大家入群一起讨论JAVA。

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值