1、JVM的内存区域划分
堆:存储new出来的对象和数组,是垃圾回收的主要区域
程序计数器:存储当前线程要执行的指令的地址
栈(虚拟机栈和本地方法栈):(虚拟机栈)存储方法调用的局部变量和操作数栈。(本地方法栈)和虚拟机栈类似,只是和本地方法有关
方法区:存储类信息,常量,静态变量和方法代码
运行时常量池:存储每个类的常量池信息
成员变量在堆上
局部变量在栈上
静态变量在方法区中
2、如何判断一个对象是否要进行GC
方法1:引用计数法:给每个对象分配一个引用计数器,如果有一个引用指向这个对象,那么引用计数器加一,否则减一,如果引用计数器为0,那么证明这个对象可以被垃圾回收器回收
方法2:可达性分析:从GCRoot开始遍历,如果没有任何一条路径可以到达某对象,那么这个对象可以被垃圾回收器回收。
3、一般从什么地方开始遍历?
1、每个栈中栈帧的局部变量表
2、常量池中引用的对象
3、方法区中静态变量引用的对象
4、引用的类型
强引用:可以找到对象也能决定对象的生死
软引用:可以找到对象也能在一定程度上决定对象的生死
弱引用:可以找到对象但是不能决定对象的生死
虚引用:不能找到对象也能不能决定对象的生死
4、常见的GC策略有哪些?
标记清除:首先将需要进行垃圾回收的对象进行标记,然后进行清除,有点是简单搞笑,缺点是会产生很多的内存碎片。
标记整理:它前两步和垃圾清除类似,但是清除完对存活的对象进行整理,优点是不会有内存碎片,但是它搬移频率较低。
标记复制,标记复制是将内存区域分成两个部分,直接拷贝存活的对象到另一个空区域,然后对当前区域整个进行GC,不会产生内存碎片,缺点是内存比较紧张的话效率比较低。
5、常见垃圾回收器和区别(CMS和G1)
CMS和G1的区别:
a)初始标记(只去找GCRoot直接关联的对象)
b)并发标记(和应用线程并发执行,去遍历所有对象)
cms会一直执行下去、G1发现老年代没有存活的对象之后就会直接回收。
c)最终标记(为了修正b产生的误差)
d)筛选回收
6、什么时候触发类加载
1)构造该类的实例
2)调用该类的静态属性和静态方法
3)使用子类时会触发父类的加载
7、什么是双亲委派模型
双亲委派模型就是当子加载器需要去加载一个类的时候,会先让其父加载器去加载这个类,只有当父加载器加载失败时子加载器才会去加载这个类,这个机制避免了加载器加载不同版本的类造成类的混乱引发安全问题。
8、怎么破坏双亲委派模型
可以参考Tomcat的做法,通过使用不同的类加载器和"破坏者"模式来实现类加载隔离和动态重新加载,以提供更强大的Web应用程序支持。