就写了一行代码,被狂虐问了这么多问题

面试官:如何在一个方法中创建一个局部byte类型数组?


小白:(是不是太基础了,暗笑)byte[] arrays = new byte[1024]。


面试官:这个局部arrays变量指向的数组对象什么时候会被GC回收?


小白:没有变量引用这个数组对象,或者arrays在虚拟机栈中的局部变量表的局部变量空间(Slot)被重用,发生垃圾回收时将会被回收掉。


面试官:数组对象没有被变量引用会被GC回收,为什么?


小白:JVM通过一系列被称为"GC Roots"的对象引用作为起始点,通过引用关系遍历对象,能被遍历到的(可到达的)对象就被判定为存活对象,没有被遍历到的(不可到达的)对象就被判定为死亡对象,找出所有存活对象来把其它对象判定为可回收对象,这就是可达性分析算法。当这个局部arrays变量所在的方法被执行时,会在当前线程的Java虚拟机栈中创建一个栈帧,这个栈帧的局部变量表中会存储arrays变量所指向的数组指针,当设置arrays=null,也就是arrays不再引用这个数组对象,arrays和这个数组对象之间的引用关系就断掉了,发生垃圾回收时,以Java虚拟机栈的栈帧中里的引用类型的变量为"GC Roots”,遍历引用关系,发现这个数组对象和"GC Roots”引用链之间没有关联了,也就是不可达,即被标识为可回收对象,等待被回收。


面试官:除了你刚刚说的Java虚拟机栈的栈帧里的引用类型局部变量可以作为"GC Roots”,还有哪些也可以作为"GC Roots”?


小白:当前所有正在被调用的方法里的引用类型的参数、局部变量和临时值;Java类的引用类型静态变量;所有当前被启动类加载器或系统类加载器加载的Java类,例如如rt.jar中的java.util.*;Java类的运行时常量池里的引用类型常量;String常量池里的引用;本地方法栈中JNI的引用;虚拟机里的一些静态数据结构里指向GC堆里的对象的引用,例如说HotSpot VM里的Universe里有很多这样的引用。


面试官:当一个对象被标识为可回收对象就一定会被回收掉吗?


小白:不一定。一个对象被标识为可回收对象后,还需要经过再次筛选,即查看这个对象有没有覆盖finalize()方法,或finalize()方法有没有被虚拟机执行过,如果没有覆盖finalize()方法或finalize()方法有没有被虚拟机执行过,如果没有覆盖finalize()方法或finalize()方法已经被虚拟机执行过,那么这个对象将会被回收掉,否则这个对象将会被放到一个叫F-Queue的队列中,这个队列中对象的finalize()方法将会被虚拟机创建的低优先级的Finalizer线程执行,在执行finalize()方法的过程中,只要这个对象和GC Roots引用链产生关联,即再次被GC Roots集合中的成员引用,那么它将被标记为不可回收对象,继续存活。


面试官:刚刚一直说到垃圾回收,那么Minor GC、Major GC和Full GC有什么区别?


小白:Minor GC指新生代GC,即发生在新生代(包括Eden区和Survivor区)的垃圾回收操作,当新生代无法为新生对象分配内存空间的时候,会触发Minor GC。因为新生代中大多数对象的生命周期都很短,所以发生Minor GC的频率很高,虽然它会触发stop-the-world,但是它的回收速度很快。Major GC清理Tenured区,用于回收老年代,出现Major GC通常会出现至少一次Minor GC。Full GC是针对整个新生代、老生代、元空间(metaspace,java8以上版本取代perm gen)的全局范围的GC。Full GC不等于Major GC,也不等于Minor GC+Major GC,发生Full GC需要看使用了什么垃圾收集器组合,才能解释是什么样的垃圾回收。

面试官:垃圾回收算法有哪些?


小白:标记-清除算法分为两部分,标记和清除。首先标记出所有需要被回收的对象,然后在标记完成后统一回收掉所有被标记的对象。这个算法简单,但是有两个缺点:一是标记和清除的效率不是很高;二是标记和清除后会产生很多的内存碎片,导致可用的内存空间不连续,当分配大对象的时候,没有足够的空间时不得不提前触发一次垃圾回收。


复制算法将可用的内存空间分为大小相等的两块,每次只是用其中的一块,当这一块被用完的时候,就将还存活的对象复制到另一块中,然后把原已使用过的那一块内存空间一次回收掉。这个算法常用于新生代的垃圾回收。复制算法解决了标记-清除算法的效率问题,以空间换时间,但是当存活对象非常多的时候,复制操作效率将会变低,而且每次只能使用一半的内存空间,利用率不高。


标记-整理算法分为三部分:一是标记出所有需要被回收的对象;二是把所有存活的对象都向一端移动;三是把所有存活对象边界以外的内存空间都回收掉。


标记-整理算法解决了复制算法多复制效率低、空间利用率低的问题,同时也解决了内存碎片的问题。


分代收集算法根据对象生存周期的不同将内存空间划分为不同的块,然后对不同的块使用不同的回收算法。一般把Java堆分为新生代和老年代,新生代中对象的存活周期短,只有少量存活的对象,所以可以使用复制算法,而老年代中对象存活时间长,而且对象比较多,所以可以采用标记-清除和标记-整理算法。

面试官:JVM运行时数据区中的方法区可以进行垃圾回收吗?


小白:方法区和堆一样,都是线程共享的内存区域,被用于存储已被虚拟机加载的类信息、即时编译后的代码、静态变量和常量等数据。根据Java虚拟机规范的规定,方法区无法满足内存分配需求时,也会抛出OutOfMemoryError异常,虽然规范规定虚拟机可以不实现垃圾收集,因为和堆的垃圾回收效率相比,方法区的回收效率实在太低,但是此部分内存区域也是可以被回收的。方法区的垃圾回收主要有两种,分别是对废弃常量的回收和对无用类的回收。当一个常量对象不再任何地方被引用的时候,则被标记为废弃常量,这个常量可以被回收。方法区中的类需要同时满足以下三个条件才能被标记为无用的类:Java堆中不存在该类的任何实例对象、加载该类的类加载器已经被回收、该类对应的java.lang.Class对象不在任何地方被引用,且无法在任何地方通过反射访问该类的方法,当满足上述三个条件的类才可以被回收,但是并不是一定会被回收,需要参数进行控制,例如HotSpot虚拟机提供了-Xnoclassgc参数进行控制是否回收。

面试官:如果让你配置JVM新生代和老年代的大小,你如何掌控?


小白:新生代配置原则:


追求响应时间优先

这种需求下,新生代尽可能设置大一些,并通过实际情况调整新生代大小,直至接近系统的最小响应时间。因为新生代比较大,发生垃圾回收的频率会比较低,响应时间快速。


追求吞吐量优先

吞吐量优先的应用,在新生代中的大部分对象都会被回收,所以,新生代尽可能设置大。此时不追求响应时间,垃圾回收可以并行进行。


避免设置过小

新生代设置过小,YGC会很频繁,同时,很可能导致对象直接进入老年代中,老年代空间不足发生FullGC。


老年代配置原则:


追求响应时间优先

这种情况下,可以使用CMS收集器,以获取最短回收停顿时间,但是其内存分配需要注意,如果设置小了会造成回收频繁并且碎片变多;如果设置大了,回收的时间会很长。所以,最优的方案是根据GClog分析垃圾回收信息,调整内存大小。


追求吞吐量优先

吞吐量优先通常需要分配一个大新生代、小老年代,将短期存活的对象在新生代回收掉。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容