深入了解Java虚拟机

概述

  1. 垃圾收集器简称GC(Garbage Collection)
  2. Java运行时内存区中,程序计数器、虚拟机栈、本地方法栈三个内存区域的内存分配和回收都具备确定性,当线程或方法结束时,内存自然就跟着回收了
  3. Java堆和方法区 存在不确定性,内存的分配和回收是动态的
  4. 垃圾收集器负责对堆进行垃圾回收时,第一件事是确定哪些对象还存活着
  5. 真正宣告一个对象死亡,至少要经历两次标记过程

引用计数算法

在对象中添加一个引用计数器,每当一个地方引用它时,计数器值就加1

当引用失效时计数器减1,当计数器为0时表示对象不能再被使用,对象“死去”,需要对该对象进行回收

可达性分析算法

1、当前主流的程序语言的内存管理系统,都是通过可达性分析算法来判断对象是否存活
2、通过称为“GC Roots”的根对象作为起始节点集,从这些节点开始根据引用关系向下搜索,如果某个对象到GC Roots间没有任何引用链相连(GC Roots到这个对象不可达时),则该对象是不可能再被使用的,需要进行垃圾回收
1)引用链:GC Roots向下搜索走过的路径

GC Roots对象有哪些

1.虚拟机栈(栈帧中的本地变量表)中引用的对象,各个线程被调用的方法堆栈中使用到的参数、局部变量、临时变量

2.方法区中类静态属性引用的对象
a)Java类中引用类型的静态变量

3.方法区中常量引用的对象
a)字符串常量池里的引用

4.本地方法栈中JNI(Native方法)引用对象

5.Java虚拟机内部的引用
a)如基本数据类型对应的Class对象,一些常驻的内存对象、系统加载类等

6.所有被同步锁持有的对象

垃圾收集器具备局部回收特征

引用

1.JDK1.2之前 Java引用
a)如果reference类型中数据中存储的数值代表另一块内存的起始地址称 reference数据是代表某块内存、某个对象的引用
b)只有引用和未引用

2.JDK1.2以后Java引用扩充
a)强引用
i.程序代码之间普遍存在的引用赋值
ii.只要强引用关系存在,垃圾收集器无法回收被引用的对象

b)软引用
i.描述一些还有用,但非必须的对象,被软引用关联的对象,在系统将要发生内存溢出异常前会把这些对象进行第二次垃圾回收,回收之后还没有足够的内存,抛出内存溢出异常
ii.JDK1.2 之后提供SoftReference类来实现软引用

c)弱引用
i.也描述非必须对象,强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集器发生为止,当垃圾收集器开始工作,无论当前内存是否足够,都会回收只有被弱引用关联的对象
ii.JDK1.2之后提供WeakReference类来实现弱引用

d)虚引用
i.虚引用也成幽灵引用,它是最弱的一种引用关系
ii.一个对象是否有虚引用存在,都不会对其生存时间构成影响,也无法通过虚引用来取得一个对象
iii.设置虚引用关联的唯一目的
1.为了能在这个对象被收集器回收时收到一个系统通知
iv.JDK1.2之后提供PhantomReference类实现虚引用

方法区回收

概述

Java虚拟机规范中说可以不要求虚拟机在方法区实现垃圾收集
方法区的垃圾收集 主要回收两部分内容
1)废弃的常量
2)不再使用的类型

垃圾收集算法

概述

从如何判定对象消亡的角度出发 垃圾收集算法分为
1)引用计数式垃圾收集(直接垃圾收集)
2)追踪式垃圾收集(间接垃圾收集)

分代收集理论

假说基础

1)弱分代假说
绝大多数对象 朝生夕灭

2)强分代假说
熬过越多垃圾收集过程的对象就越难消亡

3)跨代引用假说
跨代引用相对于同代引用来说仅占极少数(不去扫描整个老年代,也不去记录对象都有哪些跨代引用)
1)对象之间不是孤立存在的,对象之间存在跨代引用
2)新生代建立一个全局的数据结构(记忆集)。整个结构 把老年代划分成若干个小块,标识着那一块内存会存在跨代引用,发生垃圾收集时 GC Root 扫描只包含跨代引用的内存块 相对于扫描整个老年代 很划算

标记-清除算法(Mark Sweep)(最基础的垃圾收集算法)

1、标记
标记出所有要回收的对象(标记所有存活的对象)

2、清除
标记完成后,统一回收掉所有被标记的对象(回收掉未标记的对象)

3、缺点
1)执行效率不稳定
当有大量对象时,大部分都是要被清除的(新生代中的对象98%熬不过第一次垃圾回收) 所以标记和清除的两个过程的执行效率会随对象数量的增长而降低
2)内存空间的碎片化问题
当需要给较大对象分配内存时内存不够时,就会提前触发另一次垃圾收集动

标记-复制算法(复制算法)

1、解决标记清除算法 面对大量可回收对象时的效率低问题

2、过程
1)将内存容量划分成大小相等的两块 每次只使用其中的一块 ,当一块的内存用完了 就将这块内存中还存活的对象复制到另一块内存区中
2)当内存中存活对象较多时,产生大量的内存空间复制开销
3)当内存中存活对象较少时,只需要复制少数存活的对象即可

3、优点
实现简单,运行高效
4、缺点
内存缩小为原来的一半空间浪费

分代收集算法

1、分代收集算法是目前大部分JVM的垃圾收集器采用的算法。它的核心思想是根据对象存活的生命周期将内存划分为若干个不同的区域。

2、分区有
新生代 一个eden区 两个survivor区
老年代
永久代 方法区

3、在HotSpot中,基于分代的概念,GC所使 用的内存回收算法必须结合年轻代和老年代各自的特点。

4、年轻代特点:区域相对老年代较小,对象生命周期短、存活率低,回收频繁。
这种情况复制算法的回收整理,速度是最快的。复制算法的效率只和当前存活对象大小有关,因此很适用于年轻代的回收。而复制算法内存利用率不高的问题,通过hotspot中的两个survivor的设计得到缓解(新生代:老年代=1:2,新生代中eden:s0:s1=8:1:1)。

5、老年代特点:区域较大,对象生命周期长、存活率高,回收不及年轻代频繁。
这种情况存在大量存活率高的对象,复制算法明显变得不合适。一般是由标记-清除

分代的思想被现有的虚拟机广泛使用。几乎所有的垃圾回收器都区分新生代和老年代。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值