文档章节

深入理解Java虚拟机 读书笔记 之 对什么东西进行垃圾回收

清晨吼于林
 清晨吼于林
发布于 2016/10/20 07:08
字数 1380
阅读 38
收藏 0
JVM
  • 对什么东西垃圾回收?

(1)垃圾回收的内存区域,堆与方法区

        对于运行时的虚拟机栈、本地方法栈、程序计数器这3个区域,首先,这些区域在类在编译完了之后,其占用内存大小就已经固定,最关键的是,因为整个栈帧随着方法的结束,其生命周期也就结束了,因此这3个区域不用过多考虑内存回收的问题。

        对于堆与方法区,java堆与方法区只有在运行时我们才知道其所占用的大小,这部分的内存分配与回收都是动态,是我们主要考虑的地方。

(2)已死的对象,引用计数法和可达性算法

        垃圾回收器在对堆进行回收之前,第一件事情就是要判断一个对象是否已死?

        引用计数法,大致思想是,一个对象如果被引用了一次就将这个对象的计数+1,如果引用失效则-1,当这个计数为0时,在垃圾回收的时候,就有可能会被回收,但是在java中如果采用这样一种回收方式,比较难以避免循环依赖的问题。因此HotSpot实现的JVM并不是采用这样一种方法。

        可达性算法,大致思想是,从GC Root对象开始出发找寻其它对象,对于那些通过GC Root对象不可达的对象,则是需要回收的对象,那么问题来了,什么是GC Root对象。

        GC Root对象包括,虚拟机栈(栈帧中的局部变量表)中引用的对象、本地方法栈中引用的对象、方法区中常量与静态属性引用的对象。

(3)不同的引用分类,强引用、软引用、弱引用、虚引用,导致回收的策略不同

        引用,JVM中,找到一个对象,可以通过一个对象的句柄或者直接内存地址。通过句柄访问的好处,在垃圾回收的时候,不需要修改用户使用的指针,直接修改句柄指向的地址。通过直接内存访问的好处,就是快。在JDK1.2之前,Refrence的定义为,如果一个reference类型的对象里面存储一个指向其它地址的指针,那么这个就是一个引用。要么是,要么不是。我们希望描述这样一类对象,当内存空间还足够时,则能保留这个对象;如果在虚拟机执行了垃圾回收之后,内存依然比较紧张,则可以抛弃 这些对象。很多系统的缓存功能都符合这样的应用场景(?需要确认一下哪些场景,待补充?)。JDK1.2之后,扩张了引用的概念。

        强引用,类似于 Object o = new Object(),这样的,无论什么时候,都不会被垃圾回收掉。

        软引用,SoftRefrence对象,有用但是非必需的,在内存溢出之前,会对这类型的内存进行第二次回收,假如这个时候,依然没有足够的内存使用,则发生内存溢出。

        弱引用,WeakRefrence对象,有用但是非必需,强度比软引用更弱。该类型的对象只能活到第二次垃圾回收之前,在第二次垃圾回收之前,不管内存是否够用,都会回收。

        虚引用,对其什么周期完全没什么影响,但是会在回收的时候,惟一目的就是这个对象在垃圾回收的时候,会收到系统的一个通知。

(4)两次标记的回收过程

        即使是可达性分析算法中不可达的对象,也不是”非死不可“。此时处于”缓行阶段“,要真正宣告一个对象的死亡,至少需要2次标记过程。

        如果对象在可达性分析算法分析后,发现没有与GC Roots 相连接的引用链,那它会被第一次标记,并且进行一次筛选。筛选的条件是这个对象是否有必要执行finalize()函数。对于那些finalize()方法已经被虚拟机执行过的,或者finalize()方法没有被覆盖的,这两张任意一种都不必要执行。

        如果对象被判定为需要执行finalize()方法,那么这个对象会被放到F-queue队列中,JVM会启动一个低优先级Finalizer线程去执行队列中对象的finalize()方法。稍后会进行第二次标记,如果在执行finalize()方法的时候,重新将这个对象与引用链上的对象关联,则在标记时,会把这个对象从即将回收的集合中移除。

(5)方法区的回收

        JVM中的永久代(方法区是存在这个区域的)也是会进行垃圾回收的,包括那些废弃常量与废弃的类。废弃的类的判断:这个类的所有实例都已回收,加载该类的classloader已经被回收,该类对应的java.lang.Class对象没有任何地方被引用,无法在任何其它地方使用反射来访问该类中的方法。在大量使用代理、CGLib、反射、频繁使用classloader的地方都需要考虑永久代的回收

© 著作权归作者所有

清晨吼于林
粉丝 3
博文 16
码字总数 9877
作品 0
南京
私信 提问
面试中关于Java虚拟机(jvm)的问题看这篇就够了

最近看书的过程中整理了一些面试题,面试题以及答案都在我的文章中有所提到,希望你能在以问题为导向的过程中掌握虚拟机的核心知识。面试毕竟是面试,核心知识我们还是要掌握的,加油~~~ 下面...

snailclimb
2018/05/12
0
0
深入Java虚拟机之 -- 总结面试篇

系列文章: 深入Java虚拟机之 -- 总结面试篇 深入Java虚拟机之 --- JVM的爱恨情仇 JAVA 垃圾回收机制(一) --- 对象回收与算法初识 JAVA 垃圾回收机制(二) --- GC回收具体实现 深入Java虚拟机...

夏至的稻穗
05/06
0
0
JVM系列开篇:为什么要学虚拟机?

跟许多人一样,我一开始接触 Java 虚拟机只是因为面试需要用到,所以硬着头皮看看。所以很多人对于为什么要学虚拟机这个问题,他们的答案都是:因为面试。但我经过了几年的学习和实战,我发现...

陈树义
2018/11/06
0
0
用思维导图来学java虚拟机,轻松易懂!

说明 本篇文章是对周志明的《深入理解Java虚拟机》的读书笔记,思维导图使用Mindjet MindManager。曾经看到过这样一句话: 关于教育,有一个经典的定义是:把在学校里学到的东西全部忘掉,最...

小刀爱编程
2018/10/12
0
0
《深入理解Java虚拟机》读书笔记

《深入理解Java虚拟机》读书笔记 堆分配参数: -XX:+PrintGC 使用该参数,虚拟机启动后,只要遇到GC就会打印日志; -XX:+UseSerialGC 配置串行回收器; -XX:+PrintGCDeltails 可以查看详细...

卯金刀GG
2017/11/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring AOP之同一个对象方法内部自调用导致事务失效问题

对于像我这种喜欢滥用AOP的程序员,遇到坑也是习惯了,不仅仅是事务,其实只要脱离了Spring容器管理的所有对象,对于SpringAOP的注解都会失效,因为他们不是Spring容器的代理类,SpringAOP,就切入不...

xiaomin0322
33分钟前
1
0
Linux learn(七)

例行工作安排(定时任务)at,cron at 由atd服务提供,at指令所产生的的要运作的工作都以文本文件的方式写入 /var/spool/at/目录内,该工作便能等待at的这个服务取用与执行了。 权限限制相关...

lazy~
39分钟前
2
0
Vim与clang-format

前一段时间因工作需要参与了一个开源项目,在向github提交代码后提示格式校验失败。 项目的管理者告知,要想修改的代码能入库需要使用Clang-Format校验。 需要使用下面的命令对上次的修改重新...

DB_Terrill
42分钟前
1
0
Kafka写入数据保证不丢失

Kafka写入数据保证不丢失: 每个partition至少有一个follower在ISR列表中,跟上了Leader的数据同步 每次写入数据时,都要求至少写入partition leader成功,还至少一个ISR里的follower写入成功...

春哥大魔王的博客
48分钟前
1
0
git仓库删除所有提交历史记录,成为一个干净的新仓库

把旧项目提交到git上,但是会有一些历史记录,这些历史记录中可能会有项目密码等敏感信息。如何删除这些历史记录,形成一个全新的仓库,并且保持代码不变呢? 1.切换到新的分支 git check...

dragon_tech
51分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部