より多くの次の接続、ああ、私はブログのようなものを持っていたすべてが、回答の多くは、メモリのほとんどの固体理解が記憶され、ブログに詳細に記載されているがあります。そして、私の答えは、必ずしも最も正確ではありませんが、私の答えはあなたを失望させないだろう、とほぼすべての答えは、拡張の質問への答えです。
1.JVMメモリモデル
:https://www.cnblogs.com/cxiaocai/p/11483629.html
検証、製造、解像度は、4つの初期化プロセスを介して、第一のクラスのロード・サブシステムをロードした後。方法は、我々のプログラム・カウンタによって制御されるオブジェクト、メソッド、行ずつ、我々のメモリに基準点をスタック、ヒープ上のオブジェクト、プッシュ方式と呼ばれます。静的メソッドを配置する元スペース、実メモリ空間が占有され、JVMのメモリを取ることはありません。
2.JVMガベージコレクションアルゴリズム
A:3つのアルゴリズム。https://www.cnblogs.com/cxiaocai/p/11547743.html
コピーアルゴリズム、次のメモリブロックへのメモリのブロックのコピー、欠点があるコピーのためではなく、直接記憶するために使用されるメモリの左半分であります
個別のメモリブロックを掃引するかどうか、きれいなマークを回収することができ、不利オフ回復に再循環させることができるメモリの断片であります
メモリの断片化の問題を解決するために:整理するためのタグは、タグがマーカーの統合である利点のアップグレード版をクリアすることです。短所:利用可能なオブジェクトの移動による仕上げ段階、参照を更新する必要があります。
3.JVMガベージコレクタは何?そして、長所と短所を比較しますか?
:https://www.cnblogs.com/cxiaocai/p/11547743.html
5つのガベージコレクタがありますが、シリアルシリアル、パラレルParNew、パラレル清掃を高いCPUと同様に、G1の私たちのCMSと大容量メモリです。
CMSコレクタのプロセスは、複雑な初期マーク(STW)、コンカレントマークと再マーク(STW、70%を消費する)は、同時実行のリセットをクリーンアップすることを言う必要があります。
G1リカバリサーバは、大容量メモリ、回復プロセス、最初の数字(STW)、コンカレントマーク、最終フラグ(STW)、フィルタ再生(STW)を適合しました。
G1回收器的优点是STW时间是可以控制的。串行的Serial,自我觉得没啥优点,唯一的优点就是清理的彻底吧。并行的ParNew,开启多个线程去回收,一般来说线程数和CPU的核数相等,但不建议用在老年代,在老年代兼容性差。高CPU的Parallel Scavenge可能会抢占用户线程的CPU。CMS回收器需要考虑到老年代担保机制。
https://www.cnblogs.com/cxiaocai/p/11570519.html
再就是G1三个GC都是什么YoungGC优先判断一下回收一次的工作效率,不值得不执行。MixedGC清理内存块,复制算法,Full GC停止系统程序,然后采用单线程进行标记、清理和压缩整理,好空闲出来一批Region来供下一次MixedGC使用
4.什么是类的加载
答案:https://www.cnblogs.com/cxiaocai/p/11483629.html
1.验证:验证我们的编译文件(字节码文件)是否正确。
2.准备:给予类的静态常量开辟堆空间。并且赋予默认值。对象也在这个时候放置在堆空间,并且给予空值。
3.解析:将符号引用替换为直接引用,该阶段会把一些静态方法(符号引用,比如main()方法)替换为指向数据所存内存的指针或句柄等(直接引用),这是所谓的静态链接过程(类加载期间完成),动态链接是在程序运行期间完成的将符号引用替换为直接引用。就像是我们把main转化为001,将()转化为002,将这一系列的编码存在堆上。
4.初始化,将第3步的静态常量(或对象)赋值,执行静态代码块。
5.简述双亲委派
答:https://www.cnblogs.com/cxiaocai/p/11483629.html
这个简单啦,别管几层,下面给我的我一律不管,除非我是最顶层,上级交给我的,我看看我可以做吗?做不了我给我下级。
用技术一点的话就是类来了,交给我们的自定义加载器,自定义加载器先不做处理,交给我们的应用类加载器,应用类加载也先不处理,交给我们的扩展类加载器,扩展类加载器也先不处理,交给我们的启动类加载器,启动类加载器没办法了,先尝试加载一下吧,加载不了,回退给扩展类加载器,扩展类加载器也尝试一下加载吧,加载不了再交给我们的应用类加载器,应用类加载器还是处理不了只有回退给我们的自定义加载器了。
自定我们的类加载器,只要重写com.sun.org.apache.bcel.internal.util包下的ClassLoader类的findClass方法,最后调用defineClass方法。就可以实现我们的自定义加载器。
6.简述老年代担保机制
答:https://www.cnblogs.com/cxiaocai/p/11520731.html
Eden区满了后,不会立即做MinorGC,会判断一下老年代的剩余空间是否大于我们要回收的对象,够大就做MinorGC吧,如果老年代不够大了,我们会判断时候配置了-XX:-HandlePromotionFailure (jdk8以上默认设置),没配置,直接FullGC,如果配置了就去判断老年代的剩余空间是否小于我们每次minorGC后每次要放在老年代对象大小的平均值,如果老年代小于minorGC了,那么进行fullGC。
7.Java对象创建过程
答:为对象分配存储空间。开始构造对象。递归调用其超类的构造方法。进行对象实例初始化与变量初始化。执行构造方法体。使用完毕,计算GCRoot根,也就是对象不可达分析,进行垃圾回收,触发finalize方法,方法运行结束,稍后进行垃圾回收。
8.类的生命周期
答:类的完整生命周期包括7个部分:加载——验证——准备——解析——初始化——使用——卸载
9.如何判断对象可以被回收?
答:1,引用计数法(基本不用,循环引用对象永远无法销毁,可能内存溢出)
2,可达性分析算法。GCRoots根节点一般为线程栈的本地变量、静态变量、本地方法栈的变量等等。
3,常见的引用类型(强软弱虚)。
4,finalize最终判断对象存活。
如何判断一个类是无用的类
10.JVM的永久代中会发生垃圾回收么?
答:永生代也是可以回收的,条件是
1.该类的实例都被回收。
2.加载该类的classLoader已经被回收
3.该类不能通过反射访问到其方法,而且该类的java.lang.class没有被引用 当满足这3个条件时,是可以回收,但回不回收还得看jvm有没有“时间”。
11.一般用什么来分析GC日志分析
答:jmap -heap PID,jstat -gc PID,javap -c ***.class,线上尽力别用jvisualvm命令,消耗性能,想快速优化(完全不熟悉业务)可以直接通过调整eden,Survivor区来设置,记得为什么会发生fullGC,两个重要的一个动态年龄计算,另一个是老年代担保机制,熟悉业务时,可以结合业务来调整,而且在项目上线前,应该做提前的预估。
12.调优命令
答:
栈相关
-Xss->设置单个线程栈大小,比如-Xss512K,数值越小,一个线程栈里能分配的栈帧就越少,说明可以开启的线程数越多
方法区(元空间)
-XX:MetaspaceSize->设置方法区的大小,也是触发GC的阈值,比如-XX:MetaspaceSize=256M
-XX:MaxMetaspaceSiz->设置方法区的最大值,比如-XX:MaxMetaspaceSize=256M
堆相关
-Xms->jvm启动时分配的内存,比如‐Xms200m
-Xmx->jvm运行过程中分配的最大内存,比如-Xmx500m
-Xmn->设置年轻代大小,比如-Xmn2g
-XX:NewSize->设置年轻代大小 比如-XX:NewSize=2g
-XX:PretenureSizeThreshold->可以设置大对象的大小,比如-XX:PretenureSizeThreshold=100000000 单位为btye。
-XX:-HandlePromotionFailure->老年代分配担保机制参数,1.8默认开启。
-XX:-UseAdaptiveSizePolicy->禁止JVM自动优化eden和Survivor默认比例8:1:1,反之JVM默认有这个参数-XX:+UseAdaptiveSizePolicy,会导致这个比例自动变化。
-XX:SurvivorRatio->设置Eden和Survivor大小比如 -XX:SurvivorRatio =8,注意Survivor区有两个。表示Eden:Survivor=8:2,一个Survivor区占整个年轻代的1/10。
-XX:NewRatio->设置老年代和年轻代的比值大小 比如-XX:NewRatio=4,表示年老代和年轻代比值为4:1。
还有很多的命令就不依依列举了,可以去看我的博客https://www.cnblogs.com/cxiaocai/p/11570519.html
13.Minor GC与Full GC分别在什么时候发生?
答:Minor GC发生在年轻代,当eden区满的时候会出发Minor GC。
Full GC发生在老年代,回收所有堆空间的内存,Minor GC前的老年代担保机制可能出发FullGC。
14.简述对象动态年龄判断
答:https://www.cnblogs.com/cxiaocai/p/11520731.html
当我们做完minorGC以后,对象放在to区域,也就是我们Survivor的to区域,可能对象是放不下的,这时会来计算分类年龄,大致是这样来算的将所有分代年龄为1的相加,再加上分代年龄为2的,再加分代年龄为3的,依次相加,一直加到最大的分代年龄,但在相加过程中,你会发现加到分代年龄为m的对象,总大小已经放满了to区域,这时就将m到n分代年龄的对象都移置到老年代,包含m。也就是大于Survivor区域的50%时,则后面的对象,包含该年龄的对象都放置在老年代。
15.类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,他们的执行顺序
答:当创建类对象时,先初始化静态变量和静态块,然后是非静态变量和非静态代码块,然后是构造器。由于静态成员只会被初始化一次,所以如果静态成员已经被初始化过,将不会被再次初始化。
16.简述一下逃逸分析
答:-XX:+DoEscapeAnalysis
: 表示开启逃逸分析。-XX:-DoEscapeAnalysis
: 表示关闭逃逸分析 从jdk 1.7开始已经默认开始逃逸分析,如需关闭,需要指定-XX:-DoEscapeAnalysis。逃逸是指在某个方法之内创建的对象,除了在方法体之内被引用之外,还在方法体之外被其它变量引用到;这样带来的后果是在该方法执行完毕之后,该方法中创建的对象将无法被GC回收,由于其被其它变量引用。正常的方法调用中,方法体中创建的对象将在执行完毕之后,将回收其中创建的对象;故由于无法回收,即成为逃逸。
关注公众号获得更多面试和学习资料。