面试题:JVM 部分

面试题:JVM 部分

完成:第一遍

  1. 说一下 JVM 的主要组成部分?及其作用?
    堆。 堆是Java对象的存储区域,任何用new字段分配的Java对象实例和数组,都被分配在堆上,Java堆可使用-Xms -Xmx进行内存控制,值得一提的是从JDK1.7版本之后,运行时常量池从方法区移到了堆上。

    方法区。它用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据,方法区在JDK1.7版本及以前被称为永久代,从JDK1.8永久代被移除。

    虚拟机栈。虚拟机栈中执行每个方法的时候,都会创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息。

本地方法栈。与虚拟机栈发挥的作用相似,相比于虚拟机栈为Java方法服务,本地方法栈为虚拟机使用的Native方法服务,执行每个本地方法的时候,都会创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息。

  程序计数器。指示Java虚拟机下一条需要执行的字节码指令。 

以上五个区域是Java虚拟机内存划分情况,其中方法区和堆被JVM中多个线程共享,比如类的静态常量就被存放在方法区,供类对象之间共享,虚拟机栈,本地方法栈,pc寄存器是每个线程独立拥有的,不会与其他线程共享。
所以Java在通过new创建一个类对象实例的时候,一方面会在虚拟机栈中创建一个该对象的引用,另一方面会在堆上创建类对象的实例,然后将对象引用指向该对象的实例。对象引用存放在每一个方法对应的栈帧中。
195. 说一下 JVM 运行时数据区?
JVM运行时数据区包括数据隔离的数据区:方法区和堆,线程隔离的数据区:虚拟机栈,本地方法栈,程序计数器
196. 说一下堆栈的区别?
栈内存首先是一片内存区域,存储的都是局部变量,凡是定义在方法中的都是局部变量(方法外的是全局变量),for循环内部定义的也是局部变量,是先加载函数才能进行局部变量的定义,所以方法先进栈,然后再定义变量,变量有自己的作用域,一旦离开作用域,变量就会被释放。栈内存的更新速度很快,因为局部变量的生命周期都很短。
堆内存存储的是数组和对象,凡是new建立的都是在堆中,堆中存放的都是实体,实体用于封装数据,而且是封装多个,如果一个数据消失,这个实体也没有消失,还可以用,所以堆是不会随时释放的,但栈不一样,栈里存放的都是单个变量,变量被释放了,那就没有了。堆里的实体虽然不会被释放,但是会被当成垃圾,java有垃圾回收机制不定时的收取。
197. 队列和栈是什么?有什么区别?
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。
区别:1.操作的名称不同,队列的插入称为入队,队列的删除称为出队。栈的插入称为进栈,栈的删除称为出栈
2.可操作的方式不同。队列是在队尾入队,队头出队,即两边都可操作。而栈的进栈和出栈都是在栈顶进行的,无法对栈底直接进行操作
3.操作的方法不同。队列是先进先出,即队列的修改是依先进先出的原则进行的。新来的成员总要加入队尾,每次离开的成员总是队列头上。而栈为后进先出,即每次删除的总是当前栈中最新的元素,即最后插入的元素,而最先插入的被放在栈的底部,要到最后才能删除。
198. 什么是双亲委派模型?
是JVM中类加载的机制。这个模型要求除了Bootstrap ClassLoader外,其余的类加载器都要有自己的父加载器。子加载器通过组合来复用父加载器的代码,而不是使用继承。在某个类加载器class文件时,它首先委托父加载器去加载这个类,依次传递到顶层类加载器。如果顶层加载不了,子加载器才会尝试加载这个类。
199. 说一下类加载的执行过程?
类从被加载到JVM中开始到卸载为止,整个生命周期包括:加载,验证,准备,解析,初始化,使用和卸载七个阶段,其中类加载过程包括加载、验证、准备、解析和初始化五个阶段。
当一个类加载器接收到一个类加载的任务时,不会立即展开加载,而是将加载任务委托给它的父类加载器去执行,每一层的类都采用相同的方式,直到委托给最顶层的启动类加载器为止。如果父类加载器无法加载委托给它的类,便将类的加载任务退回给下一级类加载器去执行加载。
200. 怎么判断对象是否可以被回收?
如果一个程序无法引用到该对象,那么这个对象就没有到达根对象的路径,或者说从跟对象开始无法引用到该对象,该对象就是不可达的
201. Java 中都有哪些引用类型?
1.强引用
2.软引用
3.弱引用
4.虚引用
引用队列
202. 说一下 JVM 有哪些垃圾回收算法?
1.标记清除算法
2.复制算法
3.标记整理算法
4.分代收集算法
203. 说一下 JVM 有哪些垃圾回收器?
1.串行回收器
1.1 新生代串行回收器
1.2 老年代串行回收器
2.并行回收器
2.1新生代ParNew回收器
2.2新生代ParalleIGC回收器
2.3老年代ParallelOldGC
204. 详细介绍一下 CMS 垃圾回收器?
CMS垃圾回收的全称是Concurrent Mark-Sweep Collector,从名字上可以看出两点,一个使用的是并发收集,第二个使用的收集算法是Mark-Sweep.从而也可以推测出该收集器的特点是低延迟并且会有浮动垃圾的问题。
CMS收集器是为了低延迟而生,通过尽可能的并行执行垃圾回收的几个阶段来把延迟控制到最低。CMS收集器是老年代的垃圾收集器,一般情况下会有ParNew来配合执行(默认情况下也是ParNew),ParNew也是使用并行的算法来执行年轻代的回收。当然除此之外,你还可以选择使用Serial收集器来收集年轻代,不过一般很少这样使用。通过咱们说的CMS收集器是指广义上的CMS收集器,包含以下几个:ParNew(Young)GC + CMS(Old)GC + Serial GC 算法(应对核心的CMS GC某些时候的不赶趟,开销很大)。本文重点介绍一些CMS在Old区域的回收。
205. 新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别?
1. 新生代(New Generation)
大多数情况下Java程序中新建的对象都从新生代分配内存,新生代由Eden Space和两块相同大小的Survivor Space(通常又称为S0和S1或From和To)构成,可通过-Xmn参数来指定新生代的大小,也可通过-XX:SurvivorRatio来调整Eden Space及Survivor Space的大小。不同的GC方式会以不同的方式按此值来划分Eden Space和Survivor Space,有些GC方式还会根据运行状况来动态调整Eden、S0、S1的大小。
2. 老年代(Old Generation或Tenuring Generation)
用于存放新生代中经过多次垃圾回收仍然存活的对象,例如缓存对象,新建的对象也有可能在老年代上直接分配内存。主要有两种状况(由不同的GC实现来决定):一种为大对象,可通过在启动参数上设置-XX:PretenureSizeThreshold=1024(单位为字节,默认值为0)来代表当对象超过多大时就不在新生代分配,而是直接在老年代分配,此参数在新生代采用Parallel Scavenge GC时无效,Parallel Scavenge GC会根据运行状况决定什么对象直接在老年代上分配内存;另一种为大的数组对象,且数组中无引用外部对象。
新生代和老生代因为结构划分不一样,其串行收集器算法也不一样
新生代串行收集器
采用stop the world策略,步骤大概是:先从eden区扫描,把存活的对象拷贝到to区,如果to区放不下的对象直接拷贝到old区。再从from区扫描存活对象,如果对象存活次数超过阀值的就移到老年区,其他的移到to区。做完之后from和to区概念互换(from和to只是运行时的概念,其实就对应存活1区和存活2区)
206. 简述分代垃圾回收器是怎么工作的?
首先,垃圾回收器将某些特殊的对象定义为GC根对象。
接下来,垃圾回收器会对内存中的整个对象图进行遍历,它先从GC根对象开始,然后是根对象引用的其它对象,比如实例变量。回收器将访问到的所有对象都标记为存活。
存活对象在上图中被标记为蓝色。当标记阶段完成了之后,所有的存活对象都已经被标记完了。其它的那些(上图中灰色的那些)也就是GC根对象不可达的对象,也就是说你的应用不会再用到它们了。这些就是垃圾对象,回收器将会在接下来的阶段中清除它们。
207. 说一下 JVM 调优的工具?
Jconsole(Java Monitoring and Management Console)是从java5开始,在JDK中自带的java监控和管理控制台,用于对JVM中内存,线程和类等的监控,是一个基于JMX(java management extensions)的GUI性能监测工具。jconsole使用jvm的扩展机制获取并展示虚拟机中运行的应用程序的性能和资源消耗等信息。
VisualVM 是一个工具,它提供了一个可视界面,用于查看 Java 虚拟机 (Java Virtual Machine, JVM) 上运行的基于 Java 技术的应用程序(Java 应用程序)的详细信息。VisualVM 对 Java Development Kit (JDK) 工具所检索的 JVM 软件相关数据进行组织,并通过一种使您可以快速查看有关多个 Java 应用程序的数据的方式提供该信息。您可以查看本地应用程序以及远程主机上运行的应用程序的相关数据。此外,还可以捕获有关 JVM 软件实例的数据,并将该数据保存到本地系统,以供后期查看或与其他用户共享。
MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的Java heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。
208. 常用的 JVM 调优的参数都有哪些?
(1)-Xms20M
表示设置JVM启动内存的最小值为20M,必须以M为单位
(2)-Xmx20M
表示设置JVM启动内存的最大值为20M,必须以M为单位。将-Xmx和-Xms设置为一样可以避免JVM内存自动扩展。大的项目-Xmx和-Xms一般都要设置到10G、20G甚至还要高
3)-verbose:gc
表示输出虚拟机中GC的详细情况
(4)-Xss128k
表示可以设置虚拟机栈的大小为128k

你可能感兴趣的:(【JVM】)