内存模型

1、**介绍下java内存区域(运行时数据区)**?
答:线程私有:1)虚拟机栈 2)本地方法栈 3)程序计数器
线程共有:1)堆 2)方法区
直接内存:元空间
程序计数器:用来存储当前执行的程序地址。随着线程的消亡而消亡,随着线程的创建而创建。
2、说下JVM内存结构?
答:
JVM面试题 - 图1
静态编译:将java文件编译成字节码文件,这个时候class文件以静态方式存在。
类加载器:把java字节码文件加载到内存中。
堆:对象数据存放的地方,实例对象,是被所有线程共享的一块区域。
方法区:jdk1.7之前属于永久代,jdk8永久代被移除,取代而之的是元空间。
存放有被加载的类信息、常量及静态变量等。
本地方法栈:为本地方法(非java代码编写的方法)的运行提供的内存空间。
底层是C或C++写的,提供给java程序的接口。
虚拟机栈:每个线程运行的时候所需要的运行空间。
每个方法在执行的时候都会创建一个栈帧(每一次方法的调用都会创建栈帧),用于存放局部变量,操作数栈,动态链接的返回地址。
例子:栈帧1,2,3先后入栈,相当于方法1调用方法2,又调用方法3。
3、为什么程序计数器是私有的?
答:程序计数器用来存储当前线程运行到哪,字节解释器通过读取程序计数器来获取当前执行的命令。因为记录的是线程的执行情况,所以需要是私有的。
4、为什么虚拟机栈是私有的?
答:虚拟机栈用保存的是一个线程中的方法调用,需要按顺序来进行调用,线程是CPU的基本调度单位,如果虚拟机栈是共有的,那虚拟机栈存放各种线程的栈帧的话,在另一个线程出栈的时候发现是别的线程的栈帧,这样会把调用顺序给弄乱。

垃圾回收

1、怎么判断对象需要回收?
答:可达性分析算法:先根据一些GC ROOTS的对象作为起来,从这些对象的引用关系开始查找,如果一个对象没有与任何的GC ROOTS连接就可以判断这个是垃圾对象。
GC ROOTS:虚拟机栈中引用的对象,比如方法中的局部变量等;本地方法栈中;方法区中静态变量常量。
2.有哪些垃圾回收算法?
答:1)标记清除法:先标记出所有不需要回收的对象,然后直接清除掉没被标记的对象。这样会产生大量的内存碎片。
2)标记复制法:将内存区域分为两块,只有其中一块可用,在标记完对象后将对象复制到另一块区域中,再清理掉一半的全部对象。
3)标记整理法:这种先标记完所有对象,让所有对象移到一端,然后清理掉边界外的内存。
3、为什么要进行分代处理?
答:分带是根据对象熬过垃圾回收次数来进行的,在不同区域选择不同的回收策略提高效率。在新生代用标记复制就只需要移动少量的对象,而在老年代用的话就需移动大量的对象。老年代如果移动的话对回收过程有问题,如果不回收的话又对内存分配上存在问题,所以都可以。

4、CMS的回收阶段?
答:1)初始标记:标志与GC ROOTS直接相连的对象
2)并发标记:可以与用户线程并发的执行,标记玩所有相连的对象。
3)重新标记:因为前一阶段是与用于并发的,所以这一阶段要暂停用户进行来标记,怕在并发标记阶段标记之后用户又引用了某个对象。
4)并发清除
5、G1的运行过程?
答:1)初始标记
2)并发标记
3)最终标记
4)筛选回收,会估计出每个区域的回收时间,按这个时间排序,根据用户的期待的停顿时间来选择性的回收某些区域。
6、G1比起CMS有哪些优点?
答:G1整体上是基于标记整理法的,CMS是标记清除法,所以G1不会产生内存碎片。G1可以设置期待的停顿时间。
7、有哪几种引用类型?
答:强引用-就是我们日常使用中的引用,垃圾回收器怎么也不会回收的对象。
软引用-这种被引用的对象系统在发生内存溢出异常之前会对这些对象进行回收。
弱引用-被弱引用关联的对象在下次垃圾回收的时候就会被回收。
虚应用-这种引用的唯一目的就是在这个对象被回收的时候可以得到一个系统通知。
8、其中垃圾回收器的特点?
答:Serial:用单线程来进行垃圾回收,也就意味着会暂停其他线程,简单高效。
ParNew:多线程进行垃圾回收。
Parallel Scavenge:更关注的是一个可控制的吞吐量,吞吐量就是值处理器运行用户代码的时间与处理器总消耗时间的比值。这个垃圾回收器要获得较小的暂停时间就会每次少收集一些新生代内存,但是这样吞吐量就高了。
Serial Old:就是serial的老年代版本,用的标记-整理法。
Parallel Old:Parallel Scavenge的老年代版本,多线程的。
CMS:以获取回收挺短时间最短的收集器。用的是标志-清除法,初始标记和重新标记stop the world
G1:也能够得到较短的暂停时间,可以不用与其他的垃圾回收期配合使用,把内存分了块,对每块回收有个预估回收时间,如果用户设定了不超过多少暂停时间,G1就会根据每块的预估时间来进行排序,选择处理一些块,从整体来说是标记-整理,从两个块中是标记-复制。在每个快中还有其他块中对象的一些引用指针,会占用很多内存。
9、动态年龄是如何计算的?
答:对象从eden取复制到suvivor区中会将对象年龄+1,当某个小于某个年龄的对象数量大于survivor区的一半时,会选择这个年龄作为新的晋升年龄阈值。

类加载