JVM面试题

JVM

1、什么是JVM

  • J ava V irtual Machine,Java虚拟机

  • JVM是运行在操作 系统之上的,它与硬件没有直接的交互。

2、常见JVM

  • Oracle:Hotspot虚拟机(SUN公司研发)

3、执行引擎

  • 类似于翻译角色

  • 执行引擎负责解释命令(将字节码指令解释编译为机器码指令),提交操作系统执行。

4、类加载器ClassLoader

什么是类加载器

  • 作用:负责把class字节码文件加载到jvm里面

  • 细节1:class文件在文件开头有特定的文件标识

  • 细节2:类加载首先加载类信息(Class),类信息放到方法区里面,创建类实例放到堆里面

类加载器分类

第一种:启动(引导)类加载器:加载使用java.lang java.util等 (jvm自带)

第二种:扩展(平台)类加载器:负责jdk扩展类(jvm自带)

第三种:应用类加载器:负责自己项目(jvm自带)

第四种:自定义类加载器

特别说明

复制代码
Class class1 = new Demo1().getClass();
​
ClassLoader classLoader1 = class1.getClassLoader();
System.out.println(classLoader1);  //ClassLoaders$AppClassLoader@63947c6b
​
ClassLoader classLoader2 = classLoader1.getParent(); //ClassLoaders$PlatformClassLoader@776ec8df
System.out.println(classLoader2);
​
ClassLoader classLoader3 = classLoader2.getParent();
System.out.println(classLoader3); //null
  • 注意,这些类加载器本质不是父子关系,只是逻辑上的父子。

双亲委派机制

  • 沙箱安全机制

第一步,从下往上,

  • 1、当AppClassLoader加载一个class时,首先不会自己去加载,而是把类加载委派给父类加载器PlatformClassLoader去完成。

  • 2、当PlatformClassLoader加载一个class时,它首先也不会自己去加载,而是把类加载请求委派给父类加载器BootStrapClassLoader去完成。

第二步,从上往下,

  • 3、如果是启动BootStrapClassLoader加载内容,进行加载,之后结束,如果不是启动类加载器加载内容,会用PlatformClassLoader来尝试加载;

  • 4、若PlatformClassLoader加载内容,进行加载,之后结束,如果不是启动类加载器加载内容,则会使用AppClassLoader来加载

  • 5、如果AppClassLoader也加载失败,则会报出异常ClassNotFoundException

目的:安全性,避免核心类被修改。

5、方法区

方法区放什么

  • 类信息

  • 常量

  • 静态变量

  • 常量池

  • jdk7开始,字符串常量池和静态变量放到堆里面(了解)

6、栈

  • 栈也叫栈内存,主管Java程序的运行,是在线程创建时创建,每个线程都有自己的栈,它的生命周期是和线程相同的,是线程私有的

  • 栈主要作用用于执行方法的,按照后进先出原则执行,方法之间使用pc寄存器连接(指针)

  • 本地方法栈存储方法基本信息(方法名称,参数类型等)

  • 虚拟机栈执行方法

  • 栈溢出异常:

Exception in thread "main" java.lang.StackOverflowError 通常出现在递归调用时

7、堆(☆☆☆☆☆)

  • 方法区放类信息,堆放实例对象,栈对象引用

堆组成

  • 堆逻辑上分为

在jdk1.7及其之前版本,分为新生代、老年代、永久代

在jdk1.8,分为新生代、老年代、元空间

  • 新生代分为

新生区分为伊甸园区、幸存0区、幸存1区

堆实例对象过程

1、新创建一个对象,放到堆里面新生区中伊甸区里面

2、当不断创建新的对象,不断放到伊甸区里面,当伊甸区满,执行gc

3、如果gc之后对象还存活状态,进入s0或者s1里面,原则s0或者s1总有一个为空

4、每个对象默认经过15次gc,如果15次gc之后,对象还活着,进入养老区中

5、对象经过15次gc之后还活着,进入养老区里面,如果养老区满了,执行gc

6、养老区满了执行gc,gc之后还是满的状态,抛出oom异常

细节1

新生区执行gc : Minor GC

养老区执行gc: Major GC 和 Full GC

细节2

  • 什么情况下,对象进入到养老区中?

第一种情况:对象经过15次gc还存活,进入养老区中

第二种情况:对象伊甸区放不下,直接进入养老区中,如果养老区放不下直接抛出oom异常

细节3

在Java里面可以手动进行垃圾回收,调用System.gc()方法或Runtime.getRuntime().gc()方法可以触发Full GC

堆参数

堆大小调整有相应参数:

  • -Xms表示堆的起始内存,默认是物理电脑内存的1/64。

  • -Xmx表示堆的最大内存,,默认是物理电脑内存的1/4。

  • -Xmn 表示新生代堆大小,默认新生代占堆的1/3空间 ,老年代占堆的2/3空间

OOM异常

  • 什么情况下,出现堆OOM异常?

情况一:养老区满了,执行gc还满的状态,抛出oom异常

情况二:大对象,伊甸区放不下,养老区也放不下,抛出oom异常

  • java.lang.OutOfMemoryError: Java heap space

8、垃圾回收GC

  • Java是自动的垃圾回收(Garbage Collection简称GC)机制。

  • 通过垃圾回收器来对不再使用的对象完成自动的回收

  • 垃圾回收器主要负责对 和 方法区里面的内存进行回收

如何判断对象可以被回收

第一种:引用计数法(不使用了,了解)

第二种:可达性分析算法(使用)

  • 可达性分析将对象分为两类:垃圾回收的根对象(GC Root)和普通对象,对象与对象之间存在引用关系

  • 将一系列GC Root的集合作为起始点,按照从上至下的方式搜索所有能够被该合集引用到的对象(是否可达),并将其加入到该和集中,这个过程称之为标记(mark),被标记的对象是存活对象。 最终,未被探索到的对象便是死亡的,是可以回收的,标记为垃圾对象。

  • 使用可达性分析算法找到可以被回收的对象,要进行垃圾回收,首先进行 Stop-the-World,Stop-the-World停止时间越短越好

  • Stop-the-world意味着 JVM由于要执行GC而停止了应用程序的执行

  • 之后进行垃圾回收,使用不同垃圾收集算法进行回收操作

垃圾回收算法

标记清除

  • 首先使用可达性算法,找到所有存活对象,进行标记

  • 其次遍历这些对象,找到哪些对象没有被标记,回收没有标记对象

  • 缺陷:

遍历两次

产生内存碎片

复制算法

  • 首先创建大小相同空间

  • 其次复制对象到新创建空间里面

  • 第三删除原来空间对象

  • 新生区s0和s1使用复制算法

标记压缩(整理)

  • 首先使用可达性算法,找到所有存活对象,进行标记

  • 其次把所有存活对象向一端移动,清除边界以外内存

分代算法

  • 新生代使用复制算法,新生代对象存活时间很短

  • 老年代使用标记清除和标记压缩,老年代对象存活时候很长,比如连接池里面连接对象

四种引用(面试)

强引用

  • 只要对象在使用,不会被回收

  • 就算在使用,在特定情况下也会被回收

软引用

在系统要发生内存溢出(OOM)之前进行回收

弱引用

对象只能生存到下一次垃圾收集(GC)之前

虚引用

  • 无法获取实例对象,能在这个对象被收集器回收时收到一个系统通知

  • Object类有finalize()方法

这个方法执行gc之前调用这个方法,重写这个方法知道当前对象正在执行垃圾回收操作

任务

  • Java数据类型?

  • Object类有哪些方法和方法作用?

  • Redis支持数据类型有哪些?(大于5种)

  • 自我介绍

  • 1.JVM是什么? JVM的内存区域分为哪些?

    2.什么是OOM ? 什么是StackoverflowError? 有哪些方法分析?

    3.JVM 的常用参数调优你知道哪些?

    4.GC是什么? GC垃圾收集算法有哪些,算法实现机制

    5.什么是类加载器? 类加载器分类?

相关推荐
2401_882273721 小时前
pattern属性在旧版Android浏览器无效怎么办_手动验证补充【操作】
jvm·数据库·python
清水白石0081 小时前
深入 Python 循环引用与垃圾回收:如何应对内存管理的挑战
java·jvm·python
2401_8323655213 小时前
JavaScript中rest参数(...args)取代arguments的优势
jvm·数据库·python
2301_7796224113 小时前
Go语言怎么用信号量控制并发_Go语言semaphore信号量教程【入门】
jvm·数据库·python
2301_7662834413 小时前
c++如何将控制台输出保存到文件_cout重定向到txt【详解】
jvm·数据库·python
zh15702318 小时前
如何编写动态SQL存储过程_使用sp_executesql执行灵活查询
jvm·数据库·python
2401_8242226919 小时前
SQL报表统计数据量巨大_分批统计策略
jvm·数据库·python
X566119 小时前
mysql如何处理连接数过多报错_调整max_connections参数
jvm·数据库·python
m0_6091604919 小时前
MongoDB中什么是Hashed Shard Key的哈希冲突_哈希函数的分布均匀性分析
jvm·数据库·python