1、什么情况下会发生内存溢出
1)方法创建了一个很大的对象
2)产生了循环调用,死循环
3)引用了较大的全局变量
2、JVM的内存结构,Eden和Survivor比例
jvm内存结构分为两种类型:
1)线程安全:虚拟机栈,本地方法栈,程序计数器
2)非线程安全:堆,方法区
虚拟机栈:每个方法执行时,内存中创建一个空间来存储局部变量,方法的出入口等
本地方法栈:每个本地方法执行时,内存中创建一个空间来存储相关信息
程序计数器:当前程序执行class文件的行号指示器,通过改变行号来决定下一段执行
堆:每个对象的创建跟分配都是在堆上面进行,堆分为新生代,老生代。新生代有一个Eden和两个Survivor组成,默认比例是8:2.可以使用参数设置
方法区:存放类的版本,类的方法还有static修饰的对象信息
3、对象如何晋升老生代
1)当对象达到成年,经历15次GC,对象晋升为老生代
2)大的对象会直接在老生代创建
3)新生代和幸存区内存不足时,对象可能晋升到老生代
4、常见JVM参数
-Xms:初始堆大小
-Xmx:堆最大内存
-Xss:栈内存
-XX:PermSize 初始永久带内存
-XX:MaxPermSize 最大永久带内存
5、垃圾收集器,各自优缺点
串行垃圾收集器:收集时间长,停顿时间久
并发垃圾收集器:碎片空间多
CMS:并发标记清除。主要步骤:初始收集、并发标记、重新标记、并发清除、重置
G1:主要步骤:初始标记,并发标记。重新标记,复制清除
CMS的缺点就是对cpu要求比较高。G1是将内存划分成多块,所有对内段的大小有很大的要求
CMS是清除,会存在很多碎片;G1是整理,碎片空间较小
6、当出现内存溢出,如何排错
1)控制台查看错误日志
2)使用jdk自带的jvisualvm工具查看系统的堆栈日志
3)定位内存溢出空间:堆、栈
4)如果是堆溢出,查看是否创建了超大的对象
5)如果是栈内存溢出,查看是否创建了超大对象或者死循环
7、类加载器
1)引导类加载器
2)扩展类加载器
3)系统类加载器
4)自定义加载器
双亲委派:双亲委派模式会保证父类加载器会先加载类