JVM面试题

  1. JVM理论

#JVM内存模型#

  • Java内存模型(JMM)?

Java的内存模型决定了线程间的通信方式,JMM的模型是由主存和工作内存构成,两个线程想要正常通信需要将工作内存中的变量刷到主存中,另一个线程才能正确读取得到,这个也是volitile关键词的原理所在。

JVM内存结构和Java内存模型的参考资料:JVM内存结构和Java内存模型 - 知乎

  • JVM内存结构?

JVM主要由堆(JVM heap)、方法区(Method Area)、虚拟机栈(JVM stack)、本地方法区(Native Method area)、程序计数器(PCR),其中堆、方法区是线程共享的,和JVM的启动停止同步,虚拟机栈、本地方法栈、程序计数器(PCR)是线程不共享的,是线程私有的,和线程的创建停止同步。每个结构的用途如下: 

  1. 堆主要存储的是对象和数组,他是JVM内存模型中最大的一个区域,其中又能分为年轻代和老年代,年轻代又能分为Eden区和Survivor区,Survivor区又能分为S0,S1区,这是JVM中发生GC最频繁的区域。
  2. 虚拟机栈是Java方法执行的内存区域,他的基本单位是栈帧,每发生一次方法调用,就将一个栈桢入栈,方法的执行都在这个帧里面。这个帧里面包括:局部数据表,操作栈,动态链接,方法返回地址,局部变量表主要存储局部变量和方法参数,操作栈是方法执行的各种指令就放在操作栈里面的,返回地址是记录方法调用的返回地址。
  3. 本地方法区类似于虚拟机栈,只是他是为了保存通过JNI方式操作本地方法的相关信息。
  4. 方法区是保存类Class元信息、静态变量、常量等信息,其中还包括运行时常量池,其中会保存字符串常量等信息。
  5. 程序计数器则保存了每个线程执行到的字节码的指令地址。

运行时内存结构:

JVM的堆中包括新生代(Young)和老年代(Old)区域,其中新生代包括Eden和Survivor区域,其中Survivor区域包括S0和S1区域。其中新创建的对象会首先发到新生代的Eden区,但是如果对象太大也会直接放到老年代,其中新生代的GC是Minor GC,Minor GC后存活对象会被移至Survivor区,在这里会进行Major GC,每一次GC都会在S0和S1中移动复制对象,每次移动都会将该对象的年龄+1,等到满足一定的阈值就会移动到老年代中,这个阈值的默认值是15。

  1. Minor GC:是在新生代发生的GC,准确来说是在Eden区发生的GC。触发条件是Eden的空间不够,会触发异常Minor GC。
  2. Major GC:是老年代空间不够触发的GC。或者从新生代进入老年代的对象空间大于空闲空间了。
  3. Full GC:是新生代和老年代共同GC。

对象内存分配的流程图:

  • JVM堆内存分配如何保障分配对象时候的线程安全?

JVM堆在创建对象时候过程:

  1. 如果JIT分析判断该对象是逃逸对象,就直接在栈上分配,就不存在线程安全问题;
  2. 如果判断需要在JVM栈上分配,会针对该线程在TLAB上申请一块区域,该线程分配的对象登记在该区域,用以解决多线程下可能发生的线程不安全问题;
  3. 如果该对象被判断为大对象,这直接进入老年代,不会在年轻代分配空间;

#GC垃圾回收器#

  • 判断对象是否可以被回收

判断对象是否可回收的方法:

  1. 引用计数法:每个对象有一个引用计数器,每次被引用就+1,释放引用就-1,等到为0的时候就可以被回收;他的缺陷是可能存在循环引用的问题。
  2. 可达性分析:就是利用GC root到达对象的可达性来分析对象是否被引用,如果被引用就在这条引用链中,就不能回收;

GC root可以由一下对象充当:

  1. 虚拟机栈(方法)中引用的对象;

  1. 类变量(静态变量)引用的对象;

  1. 常量引用的对象;

  1. JNI引用的对象;

GC Roots 是什么?哪些对象可以作为 GC Root?看完秒懂!

GC Roots 是什么?哪些对象可以作为 GC Root?看完秒懂!_一直Tom猫的博客-CSDN博客

  • GC垃圾回收算法?

GC算法分为分代算法和分区算法,以下1,2,3是分区回收算法,4为分代回收算法:

  1. 标记-清除(Mark-Sweep)算法:就是将失效的对象做标记,等要回收的时候再清空这个对象,这个算法是分代算法的基础。缺点是标记和清除的效率都不高,并且可能存在较多的内存碎片。
  2. 标记-整理(Mark-Compact)算法:为了更充分的利用内存区域,就是将失效的对象先标记,再整理到内存区域的一侧,这样整理下来的也就是一块完整的区域,可以存放大对象,这个是在老年代中使用的GC算法,原因是老年代中对象需要回收的少,触发GC的频率低。
  3. 复制Copying算法:为了弥补标记-清除算法可能造成内存碎片的问题,就是将内存区域划分为两块,每次就只用一块,等到一块要满了,再将有效的复制到另一块,这样就能保证一块永远是空的,这个在新生代中使用的GC算法,原因是新生代中对象需要回收的多,并且触发GC的频率高。
  4. 现代的GC都分为老年代和新生代了,针对各自的特征,选中不同的GC算法。针对新生代,他们的对象生存周期短,可以选择复制这样的GC算法,这样可以留出一大片空闲空间,而老年代的内存中对象由于更新的慢,可以选择标记-整理这样的单点清理GC算法,同时也能避免内存碎片的产生。

JVM之GC算法:https://www.cnblogs.com/BlueStarWei/p/9577388.html

  • GC垃圾回收器?

GC回收器的种类:(1)serial回收器:就是在GC回收的时候停掉工作线程,他是一个串行的回收器;(2)parallel回收器:就是GC回收器是并发执行的;(3)CMS,他的全程是concurrent mark sweep,他的主要优势是在GC回收的时候不需要stop the world;(4)G1:这个是从JDK7后推出的新的GC;

CMS GC垃圾回收器

  1. CMS是并发标记清除GC回收器件,其目标是获取最短GC停顿时间,比较符合大型web server项目的使用场景。其GC阶段经过4个阶段:
  1. 初始标记:初始标记又GC root引用的对象,该过程会引发STW;
  2. 并发标记:这个是不需要STW,并发标记要回收的对象;
  3. 重新标记:这个节点重新标记并发阶段产生的新的要回收的对象;
  4. 并发清除;并发清除标记的要回收的对象;

 

CMS总结

  1. 优点:(1)并发处理效率高;(2)GC的时候不会整体停顿STW,有效降低处理时延。
  2. 缺点:(1)并发清理时会降低CPU性能;(2)标记-清理可能会造成大量内存碎片;(3)并发清理阶段还会产生垃圾,这种垃圾称为浮动垃圾,需要下一次GC时才能清理掉。

G1 GC垃圾回收器:

G1回收器会将区域划分为region,每个region可以是新生代也可以是老年代,通过控制对region的回收,做到对垃圾回收导致的STW可控。垃圾回收的阶段前3个阶段和CMS一致,只是最后一个节点需要通过混合清除来回收新生代和老年代所有的对象:

  1. 初始标记;标记GC root对象,需要暂停所有用户线程,该过程会引发STW;
  2. 并发标记;标记GC root可达的对象。
  3. 最终标记;标记在并发标记阶段产生的需回收对象。
  4. 筛选回收:对各个Region的回收成本和价值进行排序,根据用心要求的GC停顿时间来选择需要GC的Region。


G1总结:

  1. 优点:(1)并发处理效率高;(2)整体停顿STW的时间可控;(3)新生掉和老年代都分为逻辑上的region,通过GC的复制算法解决内存碎片的问题;
  2. 缺点:引入了Remembered Set来保存内存引用信息,所以增加了内存占用,所以G1一般在大内存的服务端环境使用,起步内存大小为6G。

GC回收器总结:

  1. 选择GC主要考虑的是使用场景,一般嵌入式、内存较小的选择串行GC回收器;
  2. 对于需求吞吐量大的常见可以选择并行GC回收器;
  3. 对于需要时延少的场景可以选择CMS或者G1回收器;

#JMV加载机制#

  • 双亲委派模型是什么

双亲委派模型的定义

当前ClassLoader加载的class,先调用双亲ClassLoader,如果他们加载不了,当前ClassLoader才加载,所以所有的类都会被请求到Bootstrap ClassLoader,简单理解就是能双亲做的事,就双亲来做,双亲做不了的事情就自己来做;

双亲委派模型的作用:

  1. 保障类的唯一性:ClassLoader的双亲委派模型保障一个类在类加载器的唯一性,父类已经加载了该类,子类就不再加载。
  2. 保障按需加载由于ClassLoader只有在需要某个类的时候才会加载某个类,这样避免一次性将类全部加载进入内存引发OOM。并且当ClassLoader加载一个类时,该类依赖的其他类也会由这个ClassLoader加载进来。
  • 类加载器ClassLoader原理?
  1. ClassLoader是做什么的?他是通过类的全限定名该类的字节码转化为内存中Class对象
  2. 为什么会有ClassLoader这种东西?这是由于JVM对类的加载是按需延迟加载的,并不是一次将所有类加载到内存空间里,所以需要类加载器在内存中等待需要加载的类; 
  3. ClassLoader的常用组件?最顶层的Bootstrap ClassLoader,主要负责加载rt.jar包里面的class,Extension ClassLoader主要负责加载javax里面的java ext等类,Application ClassLoader负责加载classpath里面的class文件,还有Customer ClassLoader,这个可以加载用户自定义的ClassLoader;

老大难的 Java ClassLoader 再不理解就老了:

老大难的 Java ClassLoader 再不理解就老了 - 掘金

  • ClassLoader进行加载过程?

类加载的过程是将类的字节码加载到内存中的过程,主要包括:加载-->链接-->初始化,其中链接还包括验证、准备、解析3个步骤。

  1. 加载:将class文件加载到内存,在方法区生成一个java.lang.Class对象放到方法区;
  2. 验证:验证这个class文件是否合法,包括文件格式的校验,元数据类型的校验等;
  3. 准备:为类变量分配内存空间,但此时只是初始化为默认值而非真实值,但对于final变量此时会初始化为真实值;
  4. 解析:将符号引用(相对引用)转换为直接引用,符号引用是class文件的相对表达方式,直接引用就是在该系统里地址指针,比如hello()方法为符号引用,0x12345678为直接引用;
  5. 初始化:初始化类变量成真实值,初始化静态代码段,实际执行的是类构造器<clinit>方法。

 

注意:类的初始化过程是懒加载的策略,只有当该类被使用了才会被初始化,实际就是调用<clinit>方法执行的过程;会触发类的初始化操作条件为:(1)需要创建新的对象,执行了new操作;(2)调用了类的静态变量或静态方法;(3)通过反射机制来获取某个类的时候;

  • Java 对象实例化(new)的过程?

Java的对象实例化的过程是调用<init>方法,在进行new操作的时候会执行实例化操作,实例化的过程主要是调用构造方法的过程。在进行对象实例化之前,会初始化静态变量和静态代码段,然后初始化变量和代码块,最后调用构造方法进行实例化。对象实例化过程:

 

有父子关系的初始化过程:先初始化父类,再初始化子类。

 

  • 如何判断JVM中两个类相等?

同一个类的class文件被同一个classloader加载,在JVM中才能判断这两个类对象相等。

  • Java对象(Object)在内存中的结构?

这个是指保存在JVM堆区的的java.lang.Object对象,主要包括对象头,实例数据和对齐填充数据组成。

  1. 对象头:包括(1)Mark Word,这个字段包括GC标志位,锁状态,hashcode等数据,其中锁状态包括能表征对象加锁是无锁、偏性锁、轻量级锁、重量级锁。(2)Klass Pointer(类型指针),指向方法区的类信息的指针。还有Array Length,这个当对象是数组时会存在。
  2. 实例数据:这个保存实例变量,存储对象真正的数据。
  3. 对齐填充数据由于JVM规定对象数据必须为8字节的整数,这个部分用来做数据填充。

 

Java对象在内存的结构:Java对象在内存的结构 - 掘金

Java 对象结构:Java 对象结构 - 掘金

  1. JVM应用
  • JVM调优的主要参数和工具

JVM常用参数:

  1. -Xms设置堆的最小空间大小。
  2. -Xmx设置堆的最大空间大小。
  3. -XX:NewSize设置新生代最小空间大小。
  4. -XX:MaxNewSize设置新生代最大空间大小。
  5. -XX:PermSize设置永久代最小空间大小。
  6. -XX:MaxPermSize设置永久代最大空间大小。
  7. -Xss设置每个线程的堆栈大小。 

JVM常用命令和工具:

  1. jps:java线程查看工具
  2. jstack:java线程栈的查看工具
  3. jmap:java中堆的查看工具
  4. jstat:java内置的资源和性能监控工具
  5. jinfo:实时查看和调整jvm参数

【JVM进阶之路】十:JVM调优总结:【JVM进阶之路】十:JVM调优总结 - 知乎

  • GC优化的思路?
  1. GC优化的重要指标看GC频次和GC时长,可以通过命令:jstat查看;
  2. GC优化的重要指标看CPU和内存的占用率,一般在不高于70%的利用率比较合适;
  3. 可以调整young/old分区大小和分区比例;
  4. 可以调整进入永久代的年龄阈值,默认是15次;
  5. 可以调整是否使用偏向锁;

一次简单的 JVM 调优,拿去写到简历里:

一次简单的 JVM 调优,拿去写到简历里

  • JVM问题排障的思路
  1. top查询得到哪个进程id出现问题,进而得到哪个线程id出问题,jps查询哪个线程id出现了问题;
  2. jmap查看堆内存,可以dump下来;
  3. jstack查看线程堆栈问题;
  4. jstat进行资源监控,可以查看GC数据;
  5. 其他
  • 怎么制造OOM?
  1. 对于堆中的OOM,只需要一直创建对象;
  2. 对于栈中的OOM,只需要一直创建线程或者进行递归调用就好;
  3. 对于方法区的OOM,只需要一直通过反射的方法创建类就好了;

注意:创建之前要设置堆栈的大小;

  • 对象的强引用软引用弱引用虚引用的区别?
  1. 强引用:只要引用存在,在gc root的引用链中,即可一直存在,gc不掉。最常见的一种形式:Object obj = new Object();   
  2. 软引用:gc不掉,但是当oom时,再次gc就会被gc掉,常用来做内存敏感的缓存;
  3. 弱引用:gc一次就会被gc掉,常用来做weakHashMap来做缓存;
  4. 虚引用:是无法使用的引用,一般用来通知某对象被gc了。

引用类型:强软弱虚

剖析 JDK:强引用、软引用、弱引用、虚引用有何区别?:

剖析JDK:强引用、软引用、弱引用、虚引用有何区别?_28天写作_后台技术汇_InfoQ写作社区

  • 如何对JVM进行设置,让其不发生Full GC?

这道题考察的关键是:如果不想要发生Full GC,则让对象只在新生代中进行GC,尽量不要转移至老年代,所以应该调整的是新生代的空间大小和比例。

  • Java是编译型还是解释型语言?
  1. 编译型语言是通过编译器将源码编译成机器能识别的机器码,在机器上能直接执行,比如C/C++;
  2. 解释型语言是不需要进过编译,直接通过解释器就能执行,比如JavaScript;
  3. Java的执行过程是先通过javac编译器,编译成class字节码文件,再在不同平台的JVM上解释执行,针对其中的热点代码,还会使用JIT技术直接编译成机器码,所以客观来说Java既不是编译型也不是解释型语言,是结合了他们两者的混合执行方式。
  • JVM中JIT技术的一些常见优化策略?
  1. 逃逸分析:逃逸分析的基本行为是分析对象的作用于,一个对象如果在方法中创建,但是在方法外也会被引用,这就称为该对象方法逃逸,反之如果该对象只在该方法内使用则该对象未发生方法逃逸,针对对象的逃逸分析后续可以进行一系列的优化策略。
  2. 栈上分配:一般对象存放在JVM的堆上,针对未发生方法逃逸的对象,即他的作用域只在该方法内,所以可以在JVM栈上分配对象。

标量替换:标量在程序中是指无法再分解成更小数据单元的对象,比如Java中的基础数据类型就是标量,而聚合量是指可以再分解成更小数据单元的对象,比如Java中的类对象,其至少能分解成成员变量和方法。针对未发生方法逃逸的对象,则可以直接在方法内进行标量替换,这样就不用分配到JVM的堆上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/25765.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】移除链表元素-图文解析(单链表OJ题)

LeetCode链接&#xff1a;203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 本文导航 &#x1f4ad;做题思路 &#x1f3a8;画图更好理解&#xff1a; ✍️代码实现 &#x1f5c2;️分情况讨论&#xff1a; ❄️极端情况&#xff1a; &#x1f4ad;做题思路 遍历链表…

Git报错合集

本文记录了笔者在使用 github 过程中遇到的问题&#xff0c;仅供个人使用。 目录 Could not resolve hostlocal changes to the following files would be overwritten by mergeTLS connection was non-properly terminatedUpdates were rejected because the remote contains …

普及100Hz高刷+1ms响应 微星发布27寸显示器:仅售799元

不论办公还是游戏&#xff0c;高刷及低响应时间都很重要&#xff0c;微星现在推出了一款27寸显示器PRO MP273A&#xff0c; 售价只有799元&#xff0c;但支持100Hz高刷、1ms响应时间&#xff0c;还有FreeSync技术减少撕裂。 PRO MP273A的100Hz高刷新率是其最大的卖点之一&#…

scala连接mysql数据库

scala中通常是通过JDBC组件来连接Mysql。JDBC, 全称为Java DataBase Connectivity standard。 加载依赖 其中包含 JDBC driver <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.29&l…

eclipse Java Code_Style Code_Templates

Preferences - Java - Code Style - Code Templates Eclipse [Java_Code_Style_Code_Templates_ZengWenFeng] 2023.08.07.xml 创建一个新的工程&#xff0c;不然有时候不生效&#xff0c;旧项目可能要重新导入eclipse 创建一个测试类试一试 所有的设置都生效了

Java8实战-总结11

Java8实战-总结11 Lambda表达式方法引用管中窥豹如何构建方法引用 构造函数引用 Lambda表达式 方法引用 方法引用让你可以重复使用现有的方法定义&#xff0c;并像Lambda一样传递它们。在一些情况下&#xff0c;比起使用Lambda表达式&#xff0c;它们似乎更易读&#xff0c;感…

算法竞赛入门【码蹄集新手村600题】(MT1120-1140)C语言

算法竞赛入门【码蹄集新手村600题】(MT1120-1140&#xff09;C语言 目录MT1121 小码哥考完咯MT1122阶梯IF-ELSEMT1123 元音MT1124 罗马数字MT1125 几月份MT1126 十二生肖MT1127 小码哥的属相MT1128 骰子的反面MT1129 小码哥玩骰子MT1130 骰子里面的数学MT1131 字符判断MT1132 人…

SciencePub学术 | 算法类重点SCIEEI征稿中

SciencePub学术 (www.sciencepub.cn) 刊源推荐: 算法类重点SCIE&EI征稿中&#xff01;2区闭源好刊&#xff0c;对国人非常友好。信息如下&#xff0c;录满为止&#xff1a; 一、期刊概况&#xff1a; 算法类重点SCIE&EI 【期刊简介】IF&#xff1a;6.0-6.5&#xff0…

Acwing.876 快速幂求逆元

题目 给定n组ai ,pi&#xff0c;其中p;是质数,求α;模p;的乘法逆元&#xff0c;若逆元不存在则输出impossible。 输入格式 第一行包含整数n。 接下来n行&#xff0c;每行包含一个数组ai, pi&#xff0c;数据保证p;是质数。 输出格式 输出共n行&#xff0c;每组数据输出一…

钉钉对接打通金蝶云星空获取流程实例列表详情(宜搭)接口与其他应收单接口

钉钉对接打通金蝶云星空获取流程实例列表详情&#xff08;宜搭&#xff09;接口与其他应收单接口 对接系统钉钉 钉钉&#xff08;DingTalk&#xff09;是阿里巴巴集团专为中国企业打造的免费沟通和协同的多端平台&#xff0c;提供PC版&#xff0c;Web版和手机版&#xff0c;有考…

pytorch学习——卷积神经网络——以LeNet为例

目录 一.什么是卷积&#xff1f; 二.卷积神经网络的组成 三.卷积网络基本元素介绍 3.1卷积 3.2填充和步幅 3.2.1填充&#xff08;Padding&#xff09; 填充是指在输入数据周围添加额外的边界值&#xff08;通常是零&#xff09;&#xff0c;以扩展输入的尺寸。填充可以在卷…

Git工具安装

Git 工具安装 1. 下载Git安装包2. 安装Git工具3. 简单的使用配置用户名 1. 下载Git安装包 打开官网 https://git-scm.com/downloads点击下载 2. 安装Git工具 右击以管理员身份运行 ![在这里插入图片描述](https://img-blog.csdnimg.cn/9a99a73d54824800bc87db64f71f7602.png…

避免安装这5种软件,手机广告频繁弹窗且性能下降

在我们使用手机的日常生活中&#xff0c;选择合适的应用软件对于保持良好的使用体验至关重要。然而&#xff0c;有些软件可能会给我们带来不必要的麻烦和困扰。特别是那些频繁弹窗广告、导致手机性能下降的应用程序&#xff0c;我们应该尽量避免安装它们。 首先第一种&#xf…

Python-面向对象:面向对象、成员方法 、类和对象、构造方法、魔术方法、封装、继承、类型注解、多态(抽象类(接口))

版本说明 当前版本号[20230806]。 版本修改说明20230806初版 目录 文章目录 版本说明目录知识总览图面向对象初识对象生活中数据的组织程序中数据的组织使用对象组织数据 成员方法类的定义和使用成员变量和成员方法成员方法的定义语法注意事项 类和对象现实世界的事物和类使…

快速开发平台 WebBuilder 9 发布

WebBuilder 是一款强大&#xff0c;全面和高效的应用开发和运行平台。基于浏览器的集成开发环境&#xff0c;智能化的设计&#xff0c;能轻松完成常规桌面应用和面向手机等的移动应用开发。高效、稳定和可扩展的特点&#xff0c;适合复杂企业级应用的运行。跨平台、数据库和浏览…

【Spring Cloud 四】Ribbon负载均衡

Ribbon负载均衡 系列文章目录背景一、什么是Ribbon二、为什么要有Ribbon三、使用Ribbon进行负载均衡服务提供者A代码pom文件yml配置文件启动类controller 服务提供者Bpom文件yml配置文件启动类controller 服务消费者pom文件yml文件启动类controller 运行测试 四、Ribbon的负载均…

0140 数据链路层2

目录 3.数据链路层 3.6局域网 3.7广域网 3.8数据链路层设备 部分习题 3.数据链路层 3.6局域网 3.7广域网 3.8数据链路层设备 部分习题 1.如果使用5类UTP来设计一个覆盖范围为200m的10BASE-T以太网&#xff0c;需要采用的设备是&#xff08;&#xff09; A.放大器 …

Selenium入门详细教程+实例演示

目录 1.Selenium概述 1.1什么是Selenium 1.2Selenium的优势 1.3Selenium WebDriver原理 2.Selenium环境搭建 3.Selenium 简单示例 4.八大元素定位 4.1定位方式 4.2定位方式的用法 5.Selenium API 5.1WebDriver 常用 API 5.2WebElement 常用 API 5.3代码示例 6.元素等待机…

阿里云瑶池 PolarDB 开源官网焕新升级上线

导读近日&#xff0c;阿里云开源云原生数据库 PolarDB 官方网站全新升级上线。作为 PolarDB 开源项目与开发者、生态伙伴、用户沟通的平台&#xff0c;将以开放、共享、促进交流为宗旨&#xff0c;打造开放多元的环境&#xff0c;以实现共享共赢的目标。 立即体验全新官网&…

【华秋推荐】物联网入门学习模块 ESP8266

随着全球信息技术的不断进步和普及&#xff0c;物联网成为当今备受关注的技术热点之一。通过物理和数字设备之间的连接来实现自动化和互联互通的网络。无线传感器、云计算和大数据分析等技术&#xff0c;物联网使设备能够相互交流和共享信息&#xff0c;实现智能化的自动化操作…