JVM面试题

1、什么情况下会发生堆、栈内存溢出。

栈溢出:方法执行时创建的栈帧超过了栈的深度 ,最有可能就是方法递归调用。

堆溢出:heap space表示堆空间,堆中主要存储的是对象。不断的new对象会导致堆中的空间溢出

2、JVM的内存结构,Eden和Survivor比例。

JVM区域总体分两类,heap区和非heap区。
heap区又分为:

  • Eden Space(伊甸园)、
  • Survivor Space(幸存者区)、
  • Old Gen(老年代)。

非heap区又分:

  • Code Cache(代码缓存区);
  • Perm Gen(永久代);(jdk1.8为元空间)
  • Jvm Stack(java虚拟机栈);
  • Local Method Statck(本地方法栈);

 1个Eden区和2个Survivor区(分别叫from和to)。默认比例为8:1

3、JVM内存为什么要分成新生代,老年代,持久代。新生代中为什么要分为Eden和Survivor。

Eden和Survivor的比例是8:1.

        首先说如果没有Survivor区会出现什么情况:此时每触发一次Minor GC,就会把Eden区的对象复制到老年代,这样当老年代满了之后会触发Major Gc(通常伴随着MinorGC,可以看做Full GC),比较耗时。

 

如果只有1个Survivor区,那当Eden区满了之后,就会复制对象到Survivor区,容易产生内存碎片化。严重影响性能。
所以使用2个Survivor区,始终保持有一个空的Survivor区,可以避免内存碎片化。

Survivor减少被送到老年代的对象,进而减少Full GC的发生,Survivor的预筛选保证,只有经历多次Minor GC还能在新生代中存活的对象,才会被送到老年代。

4、JVM中一次完整的GC流程是怎样的,对象如何晋升到老年代,说说你知道的几种主要的JVM参 数。

对象诞生即新生代->eden,在进行minor gc过程中,如果依旧存活,移动到from,变成Survivor,进行标记代数,如此检查一定次数后,晋升为老年代。

https://wangkang007.gitbooks.io/jvm/content/jvmcan_shu_xiang_jie.html

5、垃圾回收算法的实现原理

引用计数,标记-清除,标记-整理,复制,分代收集

https://blog.csdn.net/zdp072/article/details/51116081

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

Serial、parNew、ParallelScavenge、SerialOld、ParallelOld、CMS、G1 

CMS:
一、初始标记:此时标记需要用户线程停下来;
二、并发标记:此时标记可以和用户线程一起运行;
三、重新标记:此时标记需要用户线程停下来,主要母的是为了对并发标记的垃圾进行审核;
四、并发清除:与用户线程一起与运行进行垃圾清除;
缺点:
     1、CMS收集器对cpu资源非常敏感;
     2、CMS收集器无法清除浮动垃圾;

     3、cms基于标记清除的算法实现的,所以内存碎片会产生过多。

G1收集器:

    1、初始标记:标记GC Root能直接关联的对象,并且修改TAMS的值,让下一阶段的用户进行并发运行是,能够正确运用Region创建新对象,这阶段需要停顿,但停顿时间很短

   2、并发标记:从GC Root开始对堆进行可达性分析,找出存活的对象,这段耗时较长,但可以与用户线程并发执行。

    3、最终标记是为了修正在并发标记阶段因用户程序继续运作导致标记产生变动的那一部分的标记记录,虚拟机将这部分标记记录在线程Remembered Set中,这阶段需要停顿线程,但是可并行执行。

   4、筛选回收:首先对各个Region的回收价值和成本进行排序,根据用户所期待的GC停顿时间来制定回收计划,这个阶段也可以与用户线程并行执行,但由于只回收一部分的Region,时间是用户可控制的,而且停顿用户线程将大幅度提高收集效率。

 

7、当出现了内存溢出,你怎么排错。

首先分析是什么类型的内存溢出,对应的调整参数或者优化代码。 

https://wangkang007.gitbooks.io/jvm/content/4jvmdiao_you.html

8、JVM内存模型的相关知识了解多少,比如重排序,内存屏障,happen-before,主内存,工作 内存等。

  • 内存屏障:为了保障执行顺序和可见性的一条cpu指令 
  • 重排序:为了提高性能,编译器和处理器会对执行进行重拍 
  • happen-before:操作间执行的顺序关系。有些操作先发生。 
  • 主内存:共享变量存储的区域即是主内存 
  • 工作内存:每个线程copy的本地内存,存储了该线程以读/写共享变量的副本 

9、简单说说你了解的类加载器,可以打破双亲委派么,怎么打破。

类加载器 就是根据指定全限定名称将class文件加载到JVM内存,转为Class对象。

  • 启动类加载器(Bootstrap ClassLoader):由C++语言实现(针对HotSpot),负责将存放在\lib目录或-Xbootclasspath参数指定的路径中的类库加载到内存中。
  • 其他类加载器:由Java语言实现,继承自抽象类ClassLoader。如:
  • 扩展类加载器(Extension ClassLoader):负责加载\lib\ext目录或java.ext.dirs系统变量指定的路径中的所有类库。
  • 应用程序类加载器(Application ClassLoader)。负责加载用户类路径(classpath)上的指定类库,我们可以直接使用这个类加载器。一般情况,如果我们没有自定义类加载器默认就是用这个加载器。

打破: 线程上下文加载器(Thread Context ClassLoader)   打破双亲委派机制则不仅要继承ClassLoader类,还要重写loadClass和findClass方法。

1:自己写一个类加载器

2:重写loadclass方法

3:重写findclass方法

10、讲讲JAVA的反射机制。

Java程序在运行状态可以动态的获取类的所有属性和方法,并实例化该类,调用方法的功能 

11、你们线上应用的JVM参数有哪些。

-server (64位无需此参数)
Xms6000M 
-Xmx6000M 
-Xmn500M 
-XX:PermSize=500M 
-XX:MaxPermSize=500M 
-XX:SurvivorRatio=65536 
-XX:MaxTenuringThreshold=0 
-Xnoclassgc 
-XX:+DisableExplicitGC 
-XX:+UseParNewGC 
-XX:+UseConcMarkSweepGC 
-XX:+UseCMSCompactAtFullCollection 
-XX:CMSFullGCsBeforeCompaction=0 
-XX:+CMSClassUnloadingEnabled 
-XX:-CMSParallelRemarkEnabled 
-XX:CMSInitiatingOccupancyFraction=90 
-XX:SoftRefLRUPolicyMSPerMB=0 
-XX:+PrintClassHistogram 
-XX:+PrintGCDetails 
-XX:+PrintGCTimeStamps 
-XX:+PrintHeapAtGC 
-Xloggc:log/gc.log

12、G1和cms区别,吞吐量优先和响应优先的垃圾收集器选择。

Cms是以获取最短回收停顿时间为目标的收集器。基于标记-清除算法实现。比较占用cpu资源,切易造成碎片。 
G1是面向服务端的垃圾收集器,是jdk9默认的收集器,基于标记-整理算法实现。可利用多核、多cpu,保留分代,实现可预测停顿,可控。 、

https://blog.csdn.net/KilluaZoldyck/article/details/75081875

13、怎么打出线程栈信息。

利用jps 、 top 、jstack命令找到进程中耗时最大的线程,以及线程状态等等,同时最后还可以显示出死锁的线程 查找:Found one Java-level deadlock 即可

https://my.oschina.net/liufukin/blog/2222495

14、请解释如下jvm参数的含义:

-server -Xms512m -Xmx512m -Xss1024K

-XX:PermSize=256m -XX:MaxPermSize=512m -

XX:MaxTenuringThreshold=20 XX:CMSInitiatingOccupancyFraction=80 -

XX:+UseCMSInitiatingOccupancyOnly。

Server模式启动 
最小堆内存512m 
最大512m 
每个线程栈空间1m 
永久代256 
最大永久代256 
最大转为老年代检查次数20 
Cms回收开启时机:内存占用80% 
只以CMS的阈值来收集垃圾

注释:

-XX:+UseCMSInitiatingOccupancyOnly

-XX+UseCMSInitiatingOccupancyOnly标志来命令JVM不基于运行时收集的数据来启动CMS垃圾收集周期。而是当该标志被开启时,JVM通过CMSInitiatingOccupancyFraction的值进行每一次CMS收集,而不仅仅是第一次。大多数情况下,JVM比我们自己能作出更好的垃圾收集决策。只有当我们充足的理由(比如测试)并且对应用程序产生的对象的生命周期有深刻的认知时,才应使用该标志。

  • 6
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值