JVM篇面试宝典

1.JVM内存模型
线程独占:栈,本地方法区,程序计数器
线程共享:堆,方法区
在这里插入图片描述

1.栈:
又称方法区,线程执行方法都会创建一个栈帧,用来存储局部变量表,操作栈,动态链接,方法出口等信息
2.本地方法栈:
与栈类似,用来保存执行方法的信息,执行java方法是使用栈,执行Native方法时使用本地方法栈
3.程序计数器:
保存着当前线程的字节码位置,每个线程工作时都有独立的计数器,只为执行java方法服务,执行Native方法时,程序计数器为空
4.堆:
JVM内存管理中最大的一块,存放对象的实例,当堆没有可用空间时,就会抛出OOM异常。根据对象的存活周期不同,JVM把对象进行分代管理,由垃圾回收器进行垃圾的回收管理。
5.方法区:
又称非堆区,用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器优化后的代码等数据,1.7的永久代和1.8的元空间都是方法区的一种实现。
2.类加载与卸载
在这里插入图片描述

加载:通过类的全限定名,查找此类的字节码文件,利用字节码文件创建class对象。
验证:确保class文件符合当前JVM的要求,不会危害到JVM本身
准备:进行内存分配,为static修饰的类变量分配内存,并设置初始值(0或null),不包含final修饰的静态变量
解析:将常量池中的符号引用替换为直接引用的过程
初始化:完成静态块的执行以及静态变量的赋值,先初始化父类,再初始化当前类。只有对类主动使用时才初始化。触发条件包括:创建类的实例,访问类的静态资源,使用Class.forName反射类的时候,或者某个类的初始化
3.双亲委派机制
在这里插入图片描述

双亲委派模式,即加载器加载类时先把请求委托给自己的父类加载器执行,直到顶层的启动类加载器。父类加载器能够完成加载则返回成功,不能则子类加载器才自己尝试加载。
优点:
1.避免类的重复加载
2.避免Java核心API被篡改
4.分代回收
java自动垃圾回收:自动回收堆上不再使用的内存,之所以分代,是经历垃圾回收存活下的数据大小情况,大部分对象存活周期很短,所以针对不同的堆内存采取不同的回收频率和方法,以提高JVM的性能。
在这里插入图片描述

Eden:用于new对象时分配的内存空间,大部分初始化new的对象位于该空间。
Survivor:在Eden中经历垃圾回收后,存活下来的对象被存储在该空间。
Tenured:在survivor中存在了一段时间的对象会被挪移到该空间。
新生代(年轻代):标记-复制算法
老年代:标记-清除算法
5.回收算法
1.标记–清除算法;首先标记出所有需要被回收的对象,然后在标记完成后统一回收掉所有被标记的对象。
2.标记-复制算法:首先它把年轻代内存划分出三块区域,一块用于存放新创建的对象叫Eden区,另外两块则用于存放存活的对象分别叫 S1区和S2区。回收的时候会有两种情况,一种是把Eden和S1区的存活对象复制到S2区,第二种是把Eden和S2区的存活对象复制到S1区 ,也就是说S1区和S2这两块区域同时只会有一块使用,通过这种方式保证始终会有一块空白的q区域用于下次GC时存放存活的对象,而且原来的区域不需要考虑保留存活的对象,所以可以直接一次性清除所有对象,这要既简单直接同时也保证了清除后的内存区域的内存连续性。
标记整理算法:分为标记和整理两个阶段,标记阶段会先把存活的对象和可回收的对象标记出来;标记完之后就是进行整理了,这个阶段会把存活的对象往内存的一端移动,移动完对象后再清除可回收的对象。分代收集算法。(内存吃紧,又要避免空间碎片的场景,老年代想要避免空间碎片问题的话通常会使用标记整理法。)
6.堆和栈的区别
栈是运行时单位,代表着逻辑,内含基本数据类型和堆中对象的引用,所在区域连续,没有碎片;栈内存的更新速度快于堆内存(局部变量的声明周期短),栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不定时回收。
堆是存储单位,代表着数据,可被多个栈共享(包括成员中基本数据类型、引用和引用对象),所在区域不连续,会有碎片。
功能不同:栈内存用来存储局部变量和方法调用,而堆内存用来存储对象。无论是成员变量,局部变量还是类变量,他们都会指向的对象都存储在堆中
共享性不同:栈内存是线程私有的;堆内存是线程共享的
异常错误不同:栈内存不足(java.lang.StackOverFlowError);堆内存不足(java.lang.OutOfMenmoryError)
空间大小不同:栈空间远远小于堆
7.怎么时候触发FullGC
1.老年代空间不足
老年代只有在年轻代对象转入对象以及创建大对象、大数组时才会出现不足的情况,当执行FullGC后还是不足,则抛出异常java.OutOfMemoryError:java heap space
2.永生区(元数据空间)空间满
Permanent Generation中存放的是一些class信息等,当系统中要加载的类、反射的类和调用的方法较多时,Permanent Generation可能会被占满。如果执行FullGC仍然回收不了,就会抛出异常:java.OutOfMemoryError:PermGen space
3.CMS GC时出现promotion failed环绕concurrent mode failure
8.什么是Java虚拟机,为什么被称为是“平台无关的编程语言”
Java虚拟机是一个可执行Java字节码的虚拟机进程。Java源文件被编译成能够被Java虚拟机执行的字节码文件。Java虚拟机知道底层硬件平台的指令长度和其他特性,所以可以运行在任意的平台。
9.对象分配原则
对象优先分配在Eden区,如果Eden区没有足够的空间,虚拟机执行一次Minor GC。
大对象直接进入老年代(大对象是指需要大量连续内存空间的对象)。这样做的目的是避免在Eden区和两个Survivor区之间发生大量的内存拷贝
长期存活的对象进入老年代。徐您将为每个对象定义了一个年龄计数器,如果对象经过1次Minor GC那么对象就会进入Survivor区,之后每经过1次那么对象的年龄+1,直到达到阀值对象进入老年代
动态判断对象的年龄。如果Survivor区中相同年龄的所有对象大小总和大于Survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年区
空间分配担保。每次进行Minor GC时,JVM会计算Survivor区移至老年区的对象的平均大小,如果这个值大于老年区的剩余值大小,则进行一个Full GC,如果小于检查HandlePromotionFaileure设置,如果true则只进行Monitor GC,如果false则进行Full GC。
10.描述一下JVM加载class文件的原理机制
当运行指定程序时,JVM会将编译生成的.class文件按照需求和一定的规则加载到内存种,并组织成为一个完整的Java应用程序。这个加载过程是由类加载器来完成的,具体来说就是由ClassLoader和它的子类来实现。类加载器本身也是一个类,其实质是把类文件从硬盘读取到内存中。
类的加载方式分为隐式加载与显式加载。隐式加载指的是程序在使用new等方式创建对象时,会隐式地调用类的加载器把对应的类加载到JVM中。显示加载指的是通过直接调用class.forName()方法来把所需的类加载到JVM中。
11.类的生命周期
加载、连接、初始化、使用和卸载。
12.Java对象的结构
Java对象由三部分组成:对象头、实例数据、对齐填充。
在这里插入图片描述

13.如何判断对象可以被回收
判断对象存活一般有2种方式:
①引用计数:每个对象有一个引用计数属性,新增一个引用时计数+1,引用释放计数-1.计数为0时可以回收。
②可达性分析:从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象不可用,不可达对象。(即从GC Roots节点到该节点不可达)
14.JVM的永生代会发生Full GC吗
垃圾回收不会发生在永生代,如果永生代满了或者是超过了临界值,会触发Full GC。
15.调优命令有哪些
Sun JDK监控和故障处理命令有jps jstat jmap jhat jstack jinfo
jsp:JVM Process Status Tool,显示指定系统内所有的HotSpot虚拟机进程
jstat:JVM statistics Monitoring是用于监控虚拟机运行时状态信息的命令,可以显示虚拟机进程中的类装载,内存、垃圾收集、JIT编译等运行数据
jmap:JVM Heap Analysis Tool命令是与jmap搭配使用,用来分析jmap生成的dump,jhat内置了一个微型的HTTP/HTML服务器,生成dump的分析结果后,可以爱浏览器中查看
jstack:用于生成java虚拟机当前时刻的线程快照
jinfo:JVM Configuration info,这个命令作用是实时查看和调整虚拟机运行参数。
16.调优工具
常用调优工具分2类:jdk自带(jconsole和jvisualvm),第三方(MAT和GChisto)
17.Minor GC和Full GC发生在什么时候
新生代内存不足发生Minor GC,JVM内存不足时发生Full GC。
18.你找知道哪些JVM性能调优
-Xmx:堆内存最大限制
-XX:NewSize:新生代大小
-XX:SurvivorRatio:伊甸园空间和幸存者空间占比
-XX:NewRatio:新生代和老生代占比
19.简述java垃圾回收机制
在Java中,程序员是不需要显示的去释放对象的内存的,而是由虚拟机自行执行。在JVM中有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者当前堆内存不足时,才会触发执行。扫面那些没有被任何引用的对象,并将它们添加到要回收的集合,进行回收。
20.如何启动系统的时候设置JVM启动参数
采用“java -jar”的方式启动一个jar包里的系统,就可以采用下面的格式:
java -Xms512M -Xmx512M -Xmn256M -Xss1M -XX:PernSize=128M -XX:MaxPermSize=128M -jar App.jar

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值