关注“Java后端技术全栈”
回复“面试”获取全套面试材料
废话少说,间接开整:
第1组:JDK
、JRE
、JVM
的关系
JDK
中蕴含JRE
,也包含JDK
,而JRE
也包含JDK
。
范畴关系:JDK
>JRE
>JVM
。
具体见下图:
第2组:.java
文件与.class
文件的关系
这两者的关系须要两张图能力说明确:
第3组:class文件与JVM的关系
JVM通过类加载机制,把class文件装载进JVM中,而后JVM解析class文件的内容,于是就有了类加载过中的链接、初始化等。
第4组:类加载器关系
一张图来阐明:
第5组:办法区、堆、栈之间到底有什么关系
间接上图:
栈指向堆
如果在栈帧中有一个变量,类型为援用类型,比方:
package com.tian.my_code.test;public class JvmCodeDemo { public Object testGC(){ int op1 = 10; int op2 = 3; Object obj = new Object(); Object result=obj; return result; }}
这时候就是典型的栈中元素obj指向堆中的Object对象,result的指向和obj的指向为同一个对象。
应用命令
javac -g:vars JvmCodeDemo.java
进行编译,而后再应用
javap -v JvmCodeDemo.class >log.txt
而后关上log.txt
文件
办法区指向堆
办法区中会寄存动态变量,常量等数据。
如果是上面这种状况,就是典型的办法区中元素指向堆中的对象。
堆指向办法区
办法区中会蕴含类的信息,对象保留再堆中,创立一个对象的前提是有对应的类信息,这个类信息就在办法区中。
第6组:Minor、Major、Full GC的关系
Minor GC:产生在年老代的 GC。
- Minor GC是指从年老代空间(包含 Eden 和 Survivor 区域)回收内存。当 JVM 无奈为一个新的对象调配空间时会触发Minor GC,比方当 Eden 区满了。
- Eden区满了触发MinorGC,这时会把Eden区存活的对象复制到Survivor区,当对象在Survivor区熬过肯定次数的MinorGC之后,就会降职到老年代(当然并不是所有的对象都是这样降职的到老年代的),当老年代满了,就会报OutofMemory异样。
- 所有的MinorGC都会触发全世界的暂停(stop-the-world),进行应用程序的线程,不过这个过程十分短暂。
Major GC:产生在老年代的 GC。
- Major GC清理Tenured区(老年代)。
Full GC:新生代+老年代,比方 办法区引起年老代和老年代的回收。
第7组:Survivor与Eden的关系
对于这两者,最重要的是要明确为什么须要Survivor区?只有Eden不行吗?
如果没有Survivor,Eden区每进行一次Minor GC ,并且没有年龄限度的话, 存活的对象就会被送到老年代。这样一来,老年代很快被填满,触发Major GC(因为Major GC个别随同着Minor GC,也能够看做触发了Full GC)。老年代的内存空间远大于新生代,进行一次Full GC耗费的工夫比Minor GC长得多。
执行工夫长有什么害处?
频发的Full GC耗费的工夫很长,会影响大型程序的执行和响应速度。
可能你会说,那就对老年代的空间进行减少或者较少咯。
如果减少老年代空间,更多存活对象能力填满老年代。尽管升高Full GC频率,然而随着老年代空间加大,一旦产生Full GC,执行所须要的工夫更长。
如果缩小老年代空间,尽管Full GC所需工夫缩小,然而老年代很快被存活对象填满,Full GC频率减少。
所以Survivor的存在意义,就是缩小被送到老年代的对象,进而缩小Full GC的产生,Survivor的预筛选保障,只有经验16 次Minor GC还能在新生代中存活的对象,才会被送到老年代。
第8组:援用计数法和可达性分享算法的关系
援用计数法
给对象增加一个援用计数器,每当一个中央援用它object时技术加1,援用失去当前就减1,计数为0阐明不再援用
- 长处:实现简略,断定效率高
- 毛病:无奈解决对象互相循环援用的问题,对象A中援用了对象B,对象B中援用对象A。
public class A { public B b; }public class B { public C c; }public class C { public A a; }public class Test{ private void test(){ A a = new A(); B b = new B(); C c = new C(); a.b=b; b.c=c; c.a=a; }}
可达性剖析算法
当一个对象到GC Roots
没有援用链相连,即就是GC Roots
到这个对象不可达时,证实对象不可用。
GC Roots
品种:
❝Java 线程中,以后所有正在被调用的办法的援用类型参数、局部变量、长期值等。也就是与咱们栈帧相干的各种援用。所有以后被加载的 Java 类。Java 类的援用类型动态变量。运行时常量池里的援用类型常量(String 或 Class 类型)。JVM 外部数据结构的一些援用,比方 sun.jvm.hotspot.memory.Universe 类。用于同步的监控对象,比方调用了对象的 wait() 办法。
❞
第9组:对象的援用类型的关系
- 强援用:
User user=new User()
;咱们开发中应用最多的对象援用形式。特点:咱们平时典型编码
Object obj = new Object()
中的obj就是强援用。通过关键字new创立的对象所关联的援用就是强援用。
当
JVM
内存空间有余,JVM
宁愿抛出OutOfMemoryError
运行时谬误(OOM
),使程序异样终止,也不会靠随便回收具备强援用的“存活”对象来解决内存不足的问题。对于一个一般的对象,如果没有其余的援用关系,只有超过了援用的作用域或者显式地将相应(强)援用赋值为 null,就是能够被垃圾收集的了,具体回收机会还是要看垃圾收集策略。
- 软援用:
SoftReference<Object> object=new SoftReference<Object>(new Object())
;特点:软援用通过
SoftReference
类实现。软援用的生命周期比强援用短一些。只有当 JVM 认为内存不足时,才会去试图回收软援用指向的对象:即JVM 会确保在抛出 OutOfMemoryError 之前,清理软援用指向的对象。软援用能够和一个援用队列(ReferenceQueue)联结应用,如果软援用所援用的对象被垃圾回收器回收,Java虚拟机就会把这个软援用退出到与之关联的援用队列中。后续,咱们能够调用ReferenceQueue的poll()办法来查看是否有它所关怀的对象被回收。如果队列为空,将返回一个null,否则该办法返回队列中后面的一个Reference对象。利用场景:软援用通常用来实现内存敏感的缓存。如果还有闲暇内存,就能够临时保留缓存,当内存不足时清理掉,这样就保障了应用缓存的同时,不会耗尽内存
- 弱援用:
WeakReference<Object> object=new WeakReference<Object> (new Object()
;ThreadLocal
中有应用.弱援用通过
WeakReference
类实现。弱援用的生命周期比软援用短。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了具备弱援用的对象,不论以后内存空间足够与否,都会回收它的内存。因为垃圾回收器是一个优先级很低的线程,因而不肯定会很快回收弱援用的对象。弱援用能够和一个援用队列(
ReferenceQueue
)联结应用,如果弱援用所援用的对象被垃圾回收,Java虚拟机就会把这个弱援用退出到与之关联的援用队列中。利用场景:弱利用同样可用于内存敏感的缓存。 - 虚援用:简直没见过应用,
ReferenceQueue 、PhantomReference
。
第10组:垃圾回收算法的关系
标记-革除算法
第一步:就是找出沉闷的对象。咱们反复强调 GC 过程是逆向的, 依据 GC Roots 遍历所有的可达对象,这个过程,就叫作标记。
第二部:除了下面标记进去的对象以外,其余的都分明掉。
- 毛病:标记和革除效率不高,标记和革除之后会产生大量不间断的内存碎片
复制算法
新生代应用,新生代分中Eden:S0:S1
= 8:1:1,其中前面的1:1就是用来复制的。
当其中一块内存应用完了,就将还存活的对象复制到另外一块下面,而后把曾经应用过的内存空间一次 革除掉。
个别对象调配都是进入新生代的eden区,如果Minor GC
还存活则进入S0
区,S0
和S1
一直对象进行复制。对象存活年龄最大默认是15,大对象进来可能因为新生代不存在间断空间,所以会间接接入老年代。任何应用都有新生代的10%是空着的。
- 毛病:对象存活率高时,复制效率会较低,节约内存。
标记整顿算法
它的次要思路,就是挪动所有存活的对象,且依照内存地址程序顺次排列,而后将末端内存地址当前的内存全副回收。 然而须要留神,这只是一个现实状态。对象的援用关系个别都是非常复杂的,咱们这里不对具体的算法进行形容。咱们只须要理解,从效率上来说,个别整顿算法是要低于复制算法的。这个算法是躲避了内存碎片和内存节约。
让所有存活的对象都向一端挪动,而后间接清理掉端边界以外的内存。
从下面的三个算法来看,其实没有相对最好的回收算法,只有最适宜的算法。
第11组:垃圾收集器之间有什么关系
「新生代收集器」:Serial、ParNew
、Parallel Scavenge
「老年代收集器」:CMS
、Serial Old、Parallel Old
「整堆收集器」:G1
,ZGC
(因为不涉年代不在图中)
举荐浏览
《算法图解》.pdf
田哥:面试被问== 与equals 的区别,该怎么答复?
《一本小小的MyBatis源码剖析书》.pdf