之前一直想写博客,一直拖延,总觉得自己没什么可写的,今天早上面试了一次,发现自己太菜了,有些知识点自己看过,但是平常没用到忘记了,现在觉得还是应该记录下一些知识点,来强化自己的记忆。
今天先写下自己遇到和看到的一些面试题
什么时候一个对象会被GC?
引用计数算法
当对象的引用次数为0的时候回收对象,简单高效,缺点是如果有循环引用,会无法回收,
这个方法Java没有采用,但是Python用的是这种算法。
可达性分析算法
设立若干种根对象,当任何一个根对象到某一个对象都无法可达时,那么这个对象就是可回收的。
上图,D、E是不可达的,可以回收,如果用引用计数法的话,D、E是不可回收的。
说到GC roots(GC根),在JAVA语言中,可以当做GC roots的对象有以下几种:
1、虚拟机栈中的引用的对象。
2、方法区中的类静态属性引用的对象。
3、方法区中的常量引用的对象。
4、本地方法栈中JNI的引用的对象。
第一和第四种都是指的方法的本地变量表,第二种表达的意思比较清晰,第三种主要指的是声明为final的常量值。
垃圾收集算法
标记清除算法、复制算法、标记整理算法、分代收集算法
标记清除会造成内存不连续
复制算法会减少可使用内存
标记整理是先标记存活对象,然后整理所有存活对象,再清除未标记的对象
分代算法是上面几个算法的综合,新生代用复制算法,老年代用标记清除算法或者标记整理算法
gc又分为minor gc和full gc
minor gc是针对新生代
full gc是针对老年代,偶尔会伴随对新生代和永久代的gc
垃圾搜集器的分类
串行收集器(serial collector)只有一条GC线程,在运行是会暂停用户程序(stop the world)
并行收集器(parallel collector)有多条GC线程,也需要暂停用户程序
并发收集器(concurrent collector)有一条或多条GC线程,需要在部分阶段暂停用户程序
hotspot中的垃圾收集器
1.Serial (用于新生代,采用复制算法)(串行收集器)
2.Serial Old(用于老年代,采用标记整理算法)(串行收集器)
3.ParNew(用于新生代,采用复制算法)(并行收集器)
4.Parallel Old(用于老年代,采用标记整理算法)(并行收集器)
5.Parallel Scavenge(用新生代,采用复制算法)(并行收集器)
6.CMS(用于老年代,采用标记清除算法)(并发收集器)
7.G1(jdk1.7以后的版本推出的,维持高回收率,减少停顿,类似于concurrenthashmap的分区概念)(
java9默认gc算法是G1,且把CMS标记为废弃)
CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器,停顿时间短,用户体验就好。
基于“标记清除”算法,并发收集、低停顿,运作过程复杂,分4步:
1)初始标记:仅仅标记GC Roots能直接关联到的对象,速度快,但是需要“Stop The World”
2)并发标记:就是进行追踪引用链的过程,可以和用户线程并发执行。
3)重新标记:修正并发标记阶段因用户线程继续运行而导致标记发生变化的那部分对象的标记记录,比初始标记时间长但远比并发标记时间短,需要“Stop The World”
4)并发清除:清除标记为可以回收对象,可以和用户线程并发执行
1、3会造成停顿
由于整个过程耗时最长的并发标记和并发清除都可以和用户线程一起工作,所以总体上来看,CMS收集器的内存回收过程和用户线程是并发执行的。
JVM的两种模式
client模式和server模式
默认是client模式,server模式启动较慢,但是长时间运行的话,运行会越来越快
参考文章https://www.cnblogs.com/zuoxiaolong/category/508918.html