1. 什么是JVM?
就是 JAVA 虚拟机, 它只识别 .class 类型文件,它能够将 class 文件中的字节码指令进行识别并调用操作系统向上的 API 完成动作。
2. Java 代码的运行过程?
Java 源代码 -> 编辑器 -> 字节码文件
字节码 -> JVM -> 机器码文件
每一种平台的解释器是不同的,但是实现的虚拟机是相同的,这也就是 Java 为什么能够
跨平台的原因
3. JVM后台常驻线程有?
- 虚拟机线程
- 周期任务线程
- Gc 线程
- 编辑器线程
- 信号分发线程
4. JVM内存区域分为?
- 私有区域 ,包括程序计数器,虚拟机栈,本地方法区
- 线程共享区,包括Java堆,方法区
- 直接内存
线程私有数据区域生命周期与线程相同, 依赖用户线程的启动/结束 而 创建/销毁(在 Hotspot
VM 内
线程共享区域随虚拟机的启动/关闭而创建/销毁
运行时常量池(Runtime Constant Pool)是方法区的一部分。
5. 介绍下JAVA 虚拟机栈?
Java虚拟机栈是描述Java方法运行过程的内存模型。
Java虚拟机栈会为每一个即将运行的方法分配“栈帧”空间,用于保存改方法运行过程中所需要的一些信息,例如局部变量、操作数栈、动态链接、方法出口信息等。
Java虚拟机栈是由一个个栈帧组成,而每个栈帧中都拥有:局部变量表、操作数栈、动态链接、方法出口信息。
局部变量表的创建是在方法被执行的时候,随着栈帧的创建而创建。而且,局部变量表的大小在编译时期就确定下来了,在创建的时候只需分配事先规定好的大小即可。
Java虚拟机栈会出现两种异常:
StackOverFlowError
OutOfMemoryError
StackOverFlowError:当线程请求栈的深度超过当前Java虚拟机栈的最大深度的时候,就抛出StackOverFlowError异常。
OutOfMemoryError:
若Java虚拟机栈的内存大小允许动态扩展,且当线程请求栈时内存用完了,无法再动态扩展了,此时抛出OutOfMemoryError异常。
6. 介绍下JAVA 堆?
线程共享 :整个Java虚拟机只有一个堆,所有的线程都访问同一个堆。
在虚拟机启动时创建。
垃圾回收的主要场所。
不同的区域存放具有不同生命周期的对象。这样可以根据不同的区域使用不同的垃圾回收算法,从而更具有针对性,从而更高效。
堆的大小既可以固定也可以扩展,但主流的虚拟机堆的大小是可扩展的,因此当线程请求分配内存,但堆已满,且内存已满无法再扩展时,就抛出OutOfMemoryError。
7. 介绍下JAVA 方法区?
方法区中存放已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等。
方法区是堆的一个逻辑部分,因此和堆一样,都是线程共享的。整个虚拟机中只有一个方法区。
方法区中的信息一般需要长期存在,而且它又是堆的逻辑分区,因此用堆的划分方法,我们把方法区称为老年代。
对方法区的内存回收的主要目标是:对常量池的回收 和 对类型的卸载。长期存在。
方法区中存放数据:类信息、常量、静态变量、即时编译器编译后的代码。其中常量存储在运行时常量池中。
常量池存在于方法区。
8. 从GC的角度,JAVA堆还可以怎么分?JVM运行时内存
- 新生代,包括Edan 区,From Survivor 和 To Survivior
- 老年代
- 永久代
9. 介绍一下新生代
-
Edan区 :Java新对象的出生地(如果新创建的对象占用内存很大,则直接分配到老
年代)。当 Eden区内存不够的时候就会触发 MinorGC,对新生代区进行
一次垃圾回收。 -
Survivor From : 上一次 GC 的幸存者,作为这一次 GC 的被扫描者.
-
Survivor To : 保留了一次 MinorGC 过程中的幸存者.
10. MinorGC 的过程?
复制 , 清空, 互换
MinorGC 采用复制算法。
1: eden、 servicorFrom 复制到 ServicorTo,年龄+1
首先,把 Eden 和 ServivorFrom 区域中存活的对象复制到 ServicorTo 区域(如果有对象的年
龄以及达到了老年的标准,则赋值到老年代区),同时把这些对象的年龄+1(如果 ServicorTo 不
够位置了就放到老年区);
2: 清空 eden、 servicorFrom
然后,清空 Eden 和 ServicorFrom 中的对象;
3: ServicorTo 和 ServicorFrom 互换
最后, ServicorTo 和 ServicorFrom 互换,原 ServicorTo 成为下一次 GC 时的 ServicorFrom
区。
11. 介绍下老年代和老年代的MajorGC?
老年代的对象比较稳定,所以 MajorGC 不会频繁执行。在进行 MajorGC 前一般都先进行
了一次 MinorGC,使得有新生代的对象晋身入老年代,导致空间不够用时才触发。
MajorGC 采用标记清除算法:首先扫描一次所有老年代,标记出存活的对象,然后回收没
有标记的对象。 MajorGC 的耗时比较长,因为要扫描再回收。 MajorGC 会产生内存碎片,为了减
少内存损耗,我们一般需要进行合并或者标记出来方便下次直接分配。当老年代也满了装不下的
时候,就会抛出 OOM(Out of Memory)异常。
12. 介绍下永久代?
主要存放 Class 和 Meta(元数据)的信息,Class 在被加载的时候被
放入永久区域, 它和和存放实例的区域不同,GC 不会在主程序运行期对永久区域进行清理。所以这
也导致了永久代的区域会随着加载的 Class 的增多而胀满,最终抛出 OOM 异常。
当对象在 Survivor 区躲过一次 GC 后,其年龄就会+1。 默认情况下年龄到达 15 的对象会被
移到老生代中。
13. JAVA8 将永久代替换为元数据区
Java8 中, 永久代已经被移除,被一个称为“元数据区”(元空间)的区域所取代。元空间
的本质和永久代类似,
元空间与永久代之间最大的区别在于: 元空间并不在虚拟机中,而是使用本地内存。
因此,默认情况下,元空间的大小仅受本地内存限制。
14. GC 如何确定是垃圾?
- 引用计数法
在 Java 中,引用和对象是有关联的。如果要操作对象则必须用引用进行。因此,很显然一个简单
的办法是通过引用计数来判断一个对象是否可以回收。简单说,即一个对象如果没有任何与之关
联的引用, 即他们的引用计数都不为 0, 则说明对象不太可能再被用到,那么这个对象就是可回收
对象。
- 可达性分析
为了解决引用计数法的循环引用问题, Java 使用了可达性分析的方法。通过一系列的“GC roots”
对象作为起点搜索。如果在“GC roots”和一个对象之间没有可达路径,则称该对象是不可达的
不可达对象不等价于可回收对象, 不可达对象变为可回收对象至少要经过两次标记
过程。
15. JAVA中的四种引用类型?
-
强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的,即
使该对象以后永远都不会被用到 JVM 也不会回收。 -
软引用,用SoftReference实现,当系统内存足够时它
不会被回收,当系统内存空间不足时它会被回收。软引用通常用在对内存敏感的程序中。 -
弱引用,弱引用需要用 WeakReference 类来实现,它比软引用的生存期更短,对于只有弱引用的对象
来说,只要垃圾回收机制一运行,不管 JVM 的内存空间是否足够,总会回收该对象占用的内存。 -
虚引用,虚引用需要 PhantomReference 类来实现,它不能单独使用,必须和引用队列联合使用。 虚
引用的主要作用是跟踪对象被垃圾回收的状态。
16. JAVA类加载机制?
JVM 类加载机制分为五个部分:加载,验证,准备,解析,初始化。
-
加载, 这个阶段会在内存中生成一个代表这个类的 java.lang.Class 作为方法区这个类的各种数据的入口。
-
验证,确保 Class文件的字节流中包含的信息是否符合当前虚拟机的要求
-
准备,是正式为类变量分配内存并设置类变量的初始值阶段,public static int v = 8080,实际上变量 v 在准备阶段过后的初始值为 0 而不是 8080,但是如果声明的是常量就是8080,例如public static final int v = 8080。
-
解析,解析阶段是指虚拟机将常量池中的符号引用替换为直接引用的过程。
17. 什么是双亲委派机制?
当一个类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父
类去完成,每一个层次类加载器都是如此,因此所有的加载请求都应该传送到启动类加载其中,
只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的
Class), 子类加载器才会尝试自己去加载。
18. CMS 收集器?
Concurrent mark sweep(CMS)收集器是一种年老代垃圾收集器,其最主要目标是获取最短垃圾 回收停顿时间,和其他年老代使用标记-整理算法不同,它使用多线程的标记-清除算法。 最短的垃圾收集停顿时间可以为交互比较高的程序提高用户体验。 CMS工作机制相比其他的垃圾收集器来说更复杂,整个过程分为以下4个阶段:
-
初始标记 只是标记一下GC Roots能直接关联的对象,速度很快,仍然需要暂停所有的工作线程。
-
并发标记 进行GC Roots跟踪的过程,和用户线程一起工作,不需要暂停工作线程。
-
重新标记 为了修正在并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记 记录,仍然需要暂停所有的工作线程。
-
并发清除 清除GC Roots不可达对象,和用户线程一起工作,不需要暂停工作线程。由于耗时最长的并 发标记和并发清除过程中,垃圾收集线程可以和用户现在一起并发工作,所以总体上来看 CMS收集器的内存回收和用户线程是一起并发地执行。
19. G1收集器?
Garbage first 垃圾收集器是目前垃圾收集器理论发展的最前沿成果,相比与CMS 收集器,G1 收 集器两个最突出的改进是:
- 基于标记-整理算法,不产生内存碎片。
- 可以非常精确控制停顿时间,在不牺牲吞吐量前提下,实现低停顿垃圾回收。 G1 收集器避免全区域垃圾收集,它把堆内存划分为大小固定的几个独立区域,并且跟踪这些区域 的垃圾收集进度,同时在后台维护一个优先级列表,每次根据所允许的收集时间,优先回收垃圾 最多的区域。区域划分和优先级区域回收机制,确保 G1 收集器可以在有限时间获得最高的垃圾收 集效率。
网友评论