jvm gc调试哥哥参数 有用 看4
1.什么情况下会发生栈内存溢出。

2.详解JVM内存模型
思路: 给面试官画一下JVM内存模型图,并描述每个模块的定义,作用,以及可能会存在的问题,如栈溢出等。
我的答案:
JVM内存结构

kandao
3.JVM内存为什么要分成新生代,老年代,持久代。新生代中为什么要分为Eden和Survivor。
4. JVM中一次完整的GC流程是怎样的,对象如何晋升到老年代

5.你知道哪几种垃圾收集器,各自的优缺点,重点讲下cms和G1,包括原理,流程,优缺点。

6.JVM内存模型的相关知识了解多少,比如重排序,内存屏障,happen-before,主内存,工作内存。
思路: 先画出Java内存模型图,结合例子volatile ,说明什么是重排序,内存屏障,最好能给面试官写 以下demo说明。
我的答案:
1)Java内存模型图:
Java内存模型规定了所有的变量都存储在主内存中,每条线程还有自己的工作内存,线程的工作内存中 保存了该线程中是用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存。不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量的传递均需要自己的工作内存和主存之间进行数据同步进行。
2)指令重排序。
在这里,先看一段代码
public class PossibleReordering { static int x = 0, y = 0; static int a = 0, b = 0; public static void main(String[] args) throws InterruptedException { Thread one = new Thread(new Runnable() { public void run() { a = 1; x = b; } });Thread other = new Thread(new Runnable() { public void run() { b = 1; y = a; } }); one.start();other.start(); one.join();other.join(); System.out.println(“(” + x + “,” + y + “)”);}
1
2
运行结果可能为(1,0)、(0,1)或(1,1),也可能是(0,0)。因为,在实际运行时,代码指令可能并不是严格按照代码语句顺序执行的。大多数现代微处理器都会采用将指令乱序执行(out-of-order execution,简称OoOE或OOE)的方法,在条件允许的情况下,直接运行当前有能力立即执行的后续指令,避开获取下一条指令所需数据时造成的等待3。通过乱序执行的技术,处理器可以大大提高执行效率。而这就是
指令重排。
7.简单说说你了解的类加载器,可以打破双亲委派么,怎么打破。
双亲委派模型图:
8.说说你知道的几种主要的JVM参数
9.怎么打出线程栈信息。

10.强引用、软引用、弱引用、虚引用的区别?
11.内存模型以及分区,需要详细到每个区放什么。

12.堆里面的分区:Eden,survival (from+ to),老年代,各自的特点。

13.简述 java 垃圾回收机制?

14.java 中垃圾收集的方法有哪些?

15.java 内存模型
16.java 类加载过程?



17. 简述 java 类加载机制?
虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验,解析和初始化,最终形成可以被虚拟机直接使用的 java 类型。
18. 类加载器双亲委派模型机制?
当一个类收到了类加载请求时,不会自己先去加载这个类,而是将其委派给父类,由父类去加载,如果此时父类不能加载,反馈给子类,由子类去完成类的加载。
19.什么是类加载器,类加载器有哪些?
20.简述 java 内存分配与回收策率以及 Minor GC 和 Major GC
对象优先在堆的 Eden 区分配。
大对象直接进入老年代.
长期存活的对象将直接进入老年代当 Eden 区没有足够的空间进行分配时,虚拟机会执行一次 Minor GC.Minor Gc 通常发生在新生代的 Eden 区,在这个区的对象生存期短,往往发生 Gc 的频率较高,回收速度比较快;Full Gc/Major GC 发生在老年代,一般情况下,触发老年代 GC的时候不会触发 Minor GC,但是通过配置,可以在 Full GC 之前进行一次 Minor GC 这样可以加快老年代的回收速度。
什么时候对象会进入老年代?
新创建出来的对象一开始都会停留在新生代中,但随着JVM的运行,有些存活的长的对象会慢慢的移动到老年代中。
根据对象年龄
JVM会给对象增加一个年龄(age)的计数器,对象每“熬过”一次GC,年龄就要+1,待对象到达设置的阈值(默认为15岁)就会被移移动到老年代,可通过-XX:MaxTenuringThreshold调整这个阈值。
一次Minor GC后,对象年龄就会+1,达到阈值的对象就移动到老年代,其他存活下来的对象会继续保留在新生代中。
动态年龄判断
根据对象年龄有另外一个策略也会让对象进入老年代,不用等待15次GC之后进入老年代,他的大致规则就是,假如当前放对象的Survivor,一批对象的总大小大于这块Survivor内存的50%,那么大于这批对象年龄的对象,就可以直接进入老年代了。
如图上的A、B、D、E这四个对象,假如Survivor 2是100m,如果A + B + D的内存大小超过50m,现在D的年龄是10,那E都会被移动到老年代。实际上这个计算逻辑是这样的:年龄1 + 年龄2 + 年龄n的多个对象总和超过Survivor区的50%,那就会把年龄n以上的对象都放入老年代。
大对象直接进入老年代
如果设置了
-XX:PretenureSizeThreshold这个参数,那么如果你要创建的对象大于这个参数的值,比如分配一个超大的字节数组,此时就直接把这个大对象放入到老年代,不会经过新生代。
这么做就可以避免大对象在新生代,屡次躲过GC,还得把他们来复制来复制去的,最后才进入老年代,这么大的对象来回复制,是很耗费时间的。
浙公网安备 33010602011771号