jvm理解

jvm理解

最近看了一些jvm,以我所了解的做个总结,也希望可以帮到其他人。

1)jvm加载过程:加载、验证、准备、解析、初始化、使用、卸载

加载:加载字节码

验证:校验是否遵循java语法格式

准备:会加载类变量,类变量指的是:修饰过static语句的,比如有这条语法:static int i = 1;然后赋值过程中,内存分配默认值0,再赋值1

解析:在加载阶段会把类名、接口名、返回类型等用特定符号代替,在解析阶段再将其指向内存地址

初始化:JVM 会寻找整个 main 方法入口,从而初始化 main 方法所在的整个类当需要对一个类进行初始化时,会首先初始化类构造器,之后初始化对象构造器。

* 初始化类构造器。JVM 会按顺序收集类变量的赋值语句、静态代码块,最终组成类构造器由 JVM 执行。
* 初始化对象构造器。JVM 会按照收集成员变量的赋值语句、普通代码块,最后收集构造方法,将它们组成对象构造器,最终由 JVM 执行。

使用:运行完成阶段。

卸载:运行结束,jvm负责卸载class对象,最后销毁自己(jvm)

2)垃圾回收机制

首先说到垃圾,那么jvm是如何 定义垃圾的 ?其实就是不常用的不使用的,都会当成垃圾,怎么证明有没有使用呢?
这里我们想到的方式是计数法,就是引用就+1,断开就-1,但是存在一个问题,如果a、b、c三个对象都是垃圾,然后a、b、c相互引用,结果三个类都不能当作垃圾回收

这时候就得介绍jvm虚拟机的gc垃圾回收机制:从gc 的根(root)出发,只要被引用到的都不是垃圾
gc回收机制有三个算法:标志清除算法、复制算法和标志压缩算法

标志清除算法:分为两个阶段,标记阶段和清除阶段。被引用的则标记起来,没引用的都清除
优点:不用移动,直接清除垃圾
缺点:空间碎片多,虽然jvm虚拟机空间碎片多也可以,但是会降低性能

复制算法:内存区一分为二,然后将能被gc root引用到的都复制到另一个区,再将第一个全部删除,把第二区复制过来
优点:解决了空间碎片问题
缺点:一分为二,浪费一半的空间

标记压缩算法:这个算法是标记清除算法的升级版,标志清除算法的功能都有,多了压缩,可以减少空间碎片

3)分代思想

就是jvm不同区域用不同算法,
新生区的存活对象少,所以用复制算法好
深度了解:实际上复制算法并非1:1的区分,HotSpot虚拟机中是将其分为8:1:1,Eden、survivor、survivor三个区。
当回收时:将Eden和survivor还存活的复制到另一块survivor中,并清除掉Eden和survivor区。
老年区的存活对象多,用标记清除/标记压缩算法,不用移动

4)gc垃圾回收的引用状态:

有三种:可触达、可复活和不可触达

可触达:强引用、软引用、弱引用和虚引用
强引用:比如创建对象A a = new A();、存储list、set等集合等。不管内存够不够都不会被清除,所以需要注意内存泄漏
软引用:需要创建SoftReference对象作为软引用。内存不够的时候会清除
弱引用:可以创建WeakReference对象作为弱引用,也可以作为map中的key。不管内存够不够,gc碰到了都会处理
为什么key要弱引用呢?当value被清掉之后,key任然存在,显然不合理。
虚引用:说白了就是没什么用。不管内存够不够,gc碰到了都会处理。

注意:软/弱引用被清除之前先加入引用队列,再调用finalize函数,而虚引用是看有没有重写finalize函数,没有的话直接被回收,有的话,调用finlize函数,第二次再回收。

可复活和不可触达:当被回收之前看看是否重写了finalize函数,
如果在函数中把本对象引用给其他非垃圾对象的属性的话,那么就可以复活(可复活)
如果没重写/没有将本对象赋值给其他对象,只能等待死亡
需要注意的是:不是finalize函数执行完才会回收,可能没执行完就会被回收了,所以想要复活,必须尽快的将其赋值给其他非垃圾对象

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值