java面试集锦

持续输出面试题之JVM性能调优

2020-10-09  本文已影响0人  我可能是个假开发

什么是JVM?

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够“一次编译,到处运行”的原因。

Java类加载过程

java类加载需要经历一下7个过程:
1.加载
加载是类加载的第一个过程,在这个阶段,将完成一下三件事情:

2.验证
验证的目的是为了确保 Class文件的字节流中的信息不可危害到虚拟机。
在该阶段主要完成以下四种验证:

3.准备
准备阶段是为类的静态变量分配内存并将其初始化为默认值,这些内存都将在方法区中进行分配。准备阶段不分配类中的实例变量的内存,实例变量将会在对象实例化时随着对象一起分配在Java堆中。

//在准备阶段vlue初始值为0,在初始化阶段才会变为123。
public static int value=123;

4.解析
该阶段主要完成符号引用到直接引用的转换动作。解析动作并不一定在初始化动作完成之前,也有可能在初始化之后。

5.初始化
初始化时类加载的最后一步,前面的类加载过程,除了在加载阶段用户应用程序可以通过自定义类加载器参与之外,其余动作完全由虚拟机主导和控制。到了初始化阶段,才真正开始执行类中的定义的java程序代码。

6.使用

7.卸载

深拷贝和浅拷贝

使用深拷贝的情况下,释放内存的时候不会因为出现浅拷贝时释放同一个内存的错误。

常量池是什么

可以理解为class文件之中的资源仓库,它是class文件结构中与其他项目关联最多的数据类型,也是占用class文件空间最大的数据项目之一,同时它还是class文件中第一个出现表类型的数据项目.

由于常量池的数量是不固定的,所以在常量池入口需要放置一项u2(即2个字节)类型的数据,代表常量池容量计数值(constant-pool-count)(从1开始,将0表示不引用任何常量).

常量池中主要存放两大类常量:

常量池在class文件的什么位置?

image.png

System.gc()和Runtime.gc()会做什么事情?

用来提示JVM要进行垃圾回收。但是,立即开始还是延迟进行垃圾回收取决于JVM。

Java内存分配是怎样的?

新生代垃圾回收器和老年代垃圾回收器都有哪些?有什么区别?

新生代回收器:SerialParNewParallel Scavenge
老年代回收器:Serial OldParallel OldCMS
整堆回收器:G1
新生代垃圾回收器一般采用的是复制算法,复制算法的优点是效率高,缺点是内存利用率低;老年代回收器一般采用的是标记-整理的算法进行垃圾回收。

简述分代垃圾回收器是怎么工作的?

分代回收器有两个分区:老生代和新生代,新生代默认的空间占比总空间的 1/3,老生代的默认占比是 2/3。
新生代使用的是复制算法,新生代里有 3 个分区:EdenTo SurvivorFrom Survivor,它们的默认占比是 8:1:1,它的执行流程如下:

每次在 From Survivor 到 To Survivor 移动时都存活的对象,年龄就 +1,当年龄到达 15(默认配置是 15)时,升级为老生代。大对象也会直接进入老生代。
老生代当空间占用到达某个值之后就会触发全局垃圾收回,一般使用标记整理的执行算法。以上这些循环往复就构成了整个分代垃圾回收的整体执行流程。

说一下 JVM 调优的工具?

JDK 自带了很多监控工具,都位于 JDK 的 bin 目录下,其中最常用的是 jconsolejvisualvm 这两款视图监控工具。

Java堆的结构是什么样子的?什么是堆中的永久代(Perm Gen space)?

JVM的堆是运行时数据区,所有类的实例和数组都是在堆上分配内存。它在JVM启动的时候被创建。对象所占的堆内存是由自动内存管理系统也就是垃圾收集器回收。
堆内存是由存活和死亡的对象组成的。存活的对象是应用可以访问的,不会被垃圾回收。死亡的对象是应用不可访问尚且还没有被垃圾收集器回收掉的对象。一直到垃圾收集器把这些对象回收掉之前,他们会一直占据堆内存空间。

finalize()方法什么时候被调用?析构函数finalization)目的是什么?

垃圾回收器(garbage collector)决定回收某对象时,就会运行该对象的 finalize方法,但是在Java中很不幸,如果内存总是充足的,那么垃圾回收可能永远不会进行,也就是说 finalize可能永远不被执行,显然指望它做收尾工作是靠不住的。它最主要的用途是回收特殊渠道申请的内存。Java程序有垃圾回收器,所以一般情况下内存问题不用程序员操心。但有一种 JNI(Java Native Interface)调用non-java程序(C或C++), finalize()的工作就是回收这部分的内存。

什么是分布式垃圾回收(DGC)?它是如何工作的?

DGC叫做分布式垃圾回收。RMI使用DGC来做自动垃圾回收。因为RMI包含了跨虚拟机的远程对象的引用,垃圾回收是很困难的。DGC使用引用计数算法来给远程对象提供自动内存管理。

上一篇下一篇

猜你喜欢

热点阅读