1. 什么情况下会发生栈内存溢出。
a.方法创建了一个很大的对象,如List,Array
b.是否产生了循环调用、死循环
c.是否引用了较大的全局变量
2. JVM的内存结构,Eden和Survivor比例。
JVM内存结构分为两种类型:
线程安全:虚拟机栈、本地方法栈、程序计数器
非线程安全:堆,方法区
虚拟机栈:每个方法被执行时,都会在内存中创建一个空间用来存储方法中的局部变量,方法的出入口等信息。
本地方法栈:每个本地方法被执行时,都会创建一个内存空间,用来存储本地方法中的局部变量,方法的出入口等信息。
程序计数器:是当前程序所执行的class文件的行号指示器,通过改变行号来决定下一段要执行的字节码指令,跳转,循环,异常处理
堆:每一个对象的创建跟分配都是在堆上面进行的,堆分为新生代,老生代。新生代有一个Eden和两个Survivor组成,默认比例是8:2。也可以使用-XXSurvivorRatio来改变百分比。
方法区:用来存放类的版本,类的方法还有static修饰的对象等信息。
==================================================================
3. jvm中一次完整的GC流程是怎样的,对象如何晋升到老年代,说说你知道的几种主要的jvm参数。
GC流程图
对象晋升老生代一共有三个可能:
1.当对象达到成年,经历过15次GC(默认15次,可配置),对象就晋升为老生代
2.大的对象会直接在老生代创建
3.新生代跟幸存区内存不足时,对象可能晋升到老生代
jvm参数:
-Xms:初始堆大小
-Xmx:堆最大内存
-Xss:栈内存
-XX:PermSize 初始永久带内存
-XX:MaxPermSize 最大永久带内存
==================================================================
4. 你知道哪几种垃圾收集器,各自的优缺点,重点讲下cms,包括原理,流程,优缺点
串行垃圾收集器:收集时间长,停顿时间久
并发垃圾收集器:碎片空间多
CMS:并发标记清除。他的主要步骤有:初始收集,并发标记,重新标记,并发清除(删除),重置
G1:主要步骤:初始标记,并发标记,重新标记,复制清除(整理)
CMS的缺点是对cpu的要求比较高。G1是将内存化成了多块,所有对内段的大小有很大的要求
CMS是清除,所以会存在很多的内存碎片。G1是整理,所以碎片空间较小
==================================================================
5. 垃圾回收算法的实现原理。
常用的垃圾回收算法有两种: 引用计数和可达性分析
引用计数是增加一个字段来标识当前的引用次数,引用计数为0的就是可以GC的。但是引用计数不能解决循环引用的问题
可达性分析:就是通过一系列GC ROOT的对象作为起点,向下搜索,搜索所有没有与当前对象GC ROOT 有引用关系的对象。这些对象就是可以GC的。在此我向大家推荐一个架构学习交流圈。交流学习指导伪鑫:1253431195(里面有大量的面试题及答案)里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多
==================================================================
6. 当出现了内存溢出,你怎么排错。
1.首先控制台查看错误日志
2.然后使用jdk自带的jvisualvm工具查看系统的堆栈日志
3.定位出内存溢出的空间:堆,栈还是永久代(jdk8以后不会出现永久代的内存溢出)。
4.如果是堆内存溢出,看是否创建了超大的对象
5.如果是栈内存溢出,看是否创建了超大的对象,或者产生了死循环。
==================================================================
7. JVM内存模型的相关知识了解多少,比如重排序,内存屏障,happen-before,主内存,工作内存等。
重排序:jvm虚拟机允许在不影响代码最终结果的情况下,可以乱序执行。
内存屏障:可以阻挡编译器的优化,也可以阻挡处理器的优化
happens-before原则:
1:一个线程的A操作总是在B之前,那多线程的A操作肯定实在B之前。
2:monitor 再加锁的情况下,持有锁的肯定先执行。
3:volatile修饰的情况下,写先于读发生
4:线程启动在一起之前 strat
5:线程死亡在一切之后 end
6:线程操作在一切线程中断之前
7:一个对象构造函数的结束都该对象的finalizer的开始之前
8:传递性,如果A肯定在B之前,B肯定在C之前,那A肯定是在C之前。
主内存:所有线程共享的内存空间
工作内存:每个线程特有的内存空间
==================================================================
8. 简单说说你了解的类加载器。
类加载器主要分为:引导类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader),系统类加载器(App ClassLoader)和自定义加载器(Custom ClassLoader)
双亲委派:双亲委派模式会保证父类加载器先加载类
==================================================================
9. 讲讲JAVA的反射机制。
在运行是,对于任意一个类,都能知道当前类的方法和属性,对于任意一个类,都能调用类的方法和属性,着用动态加载机制就是Java的反射机制。在此我向大家推荐一个架构学习交流圈。交流学习指导伪鑫:1253431195(里面有大量的面试题及答案)里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多
==================================================================
10. 你们线上应用的JVM参数有哪些。
-XX:PermSize=128M
-XX:MaxPermSize=512m
-XX:PermSize=128M
-XX:MaxPermSize=512m
-Xms512m
-Xmx1024m
-XX:PermSize=640m
-XX:MaxPermSize=1280m
-XX:NewSize=64m
-XX:MaxNewSize=256m
-verbose:gc
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
==================================================================
11. g1和cms区别,吞吐量优先和响应优先的垃圾收集器选择。
CMS:并发标记清除。他的主要步骤有:初始收集,并发标记,重新标记,并发清除(删除),重置
G1:主要步骤:初始标记,并发标记,重新标记,复制清除(整理)
CMS的缺点是对cpu的要求比较高。G1是将内存化成了多块,所有对内段的大小有很大的要求
CMS是清除,所以会存在很多的内存碎片。G1是整理,所以碎片空间较小
吞吐量优先:G1
响应优先:CMS
==================================================================
12. 请解释如下jvm参数的含义: -server -Xms512m -Xmx512m -Xss1024K -XX:PermSize=256m -XX:MaxPermSize=512m -XX:MaxTenuringThreshold=20 XX:CMSInitiatingOccupancyFraction=80 -XX:+UseCMSInitiatingOccupancyOnly。
-server:服务器模式
-Xms512m :初始堆空间
-Xmx512m:最大堆空间
-Xss1024K :栈空间
-XX:PermSize=256m :初始永久带空间
-XX:MaxPermSize=512m :最大永久带空间
-XX:MaxTenuringThreshold=20 :对象的生命周期
XX:CMSInitiatingOccupancyFraction=80 :老年代的内存在使用到70%的时候,就开始启动CMS了
-XX:+UseCMSInitiatingOccupancyOnly:它就只会按照你设置的比率来启动CMS GC了