首页 > 编程知识 正文

jvm面试题及答案2020,java jvm面试题

时间:2023-05-05 18:36:38 阅读:32359 作者:4853

文章1 .什么是JVM? 1.1JDK和JVM有什么区别? 1.2常见的JDK制造商是什么? 1.3 OracleJDK和OpenJDK有什么区别? 1.4开发使用哪个版本的JDK? 生产环境是什么? 为什么这么选? 什么是Java字节码? 2.1字节码文件包含什么? 2.2什么是常数? 2.3如何理解常量池? 3. JVM的运行时数据区是什么? 3.1什么是堆内存? 3.2堆内存包括哪些部分? 3.3什么是非堆内存? 4 .什么是内存溢出? 4.1什么是内存泄漏? 4.2内存泄漏与内存溢出有什么关系? 5 .分析对象内存占有量5.1是根据对象内存占有量计算的吗? 5.2目标头包括哪些部分? 6 .常见的JVM启动参数是什么? 6.1配置堆内存XMX时需要考虑哪些因素? 6.2假设物理内存为8G,安装多少内存比较合适? 6.3(xmx设置的值与JVM进程占用的内存有什么关系? 6.4如何打开GC日志? 指定使用6.5g1垃圾收集器启动Hello程序7. Java8的缺省情况下使用的垃圾收集器。 7.1 Java11的默认垃圾收集器是什么? 7.2常见的垃圾收集器是什么? 7.3什么是串行垃圾收集? 7.4什么是并行垃圾收集? 7.5什么是同时垃圾收集器? 7.6什么是增量垃圾收集? 7.7什么是年轻一代? 7.8GC姿势是什么? 7.9 GC姿势和STW姿势有什么区别? 8 .如果CPU使用率突然上升,如何排除? 8.1如果系统响应缓慢,如何进行故障诊断? 8.2系统性能一般如何测量? 9 .你使用过什么JVM相关的工具? 9.1显示JVM进程号的命令是什么? 9.2如何检查剩下的内存? 9.3显示线程堆栈的工具是什么? 9.4使用什么工具获取堆内存转储? 9.5内存Dump时的注意事项是什么? 9.6如何处理jmap转储堆内存的大致参数? 9.7转储文件为什么以. hprof结尾? 9.8内存Dump完成后,用什么工具分析? 9.9忘记使用什么参数的话,你一般怎么处理?

让大家总结一下:

1 .什么是JVM? JVM的全名是Java虚拟机,在中文中称为Java虚拟机。

JVM是运行Java程序的基础平台,与Java支持库一起构成了Java程序的运行环境。 分为JVM规范和JVM实现两部分。 简而言之,Java虚拟机是能够执行标准Java字节码的虚拟机。

1.1JDK和JVM有什么区别? 现在的JDK、JRE、JVM一般都是一套出现的。

JDK=JRE开发调试诊断工具

JRE=JVM Java标准库

1.2常见的JDK制造商是什么? 典型的JDK制造商包括:

包括甲骨文公司、Hotspot虚拟机和GraalVM虚拟机; 分为OpenJDK和OracleJDK

版本。 IBM公司、J9虚拟机、用于IBM产品套件的Azul Systems公司、高性能Zing和开源Zulu阿里巴巴、Dragonwell为阿里开发的OpenJDK定制版亚马逊、correto openjddk

还有开源、试验性的JVM实现吗,包括Go.JVM 1.3 OracleJDK和OpenJDK之间的区别? 不同版本的JDK一般符合Java虚拟机的规范。

两者的区别一般如下。

两种类型的JDK提供的工具包略有不同。 例如,jmc等有版权的工具。 有些协议和配置不同,例如美国出口限制的加密算法。 其他细微差异,例如JRE中的某些专用API不同。 1.4开发使用哪个版本的JDK? 生产环境是什么? 为什么这么选? 选择哪个版本需要考虑研发团队的具体情况。 例如,机器的操作系统、团队成员的掌握情况、与传统项目的兼顾等。

目前,Java最受欢迎的长期维护版本是Java8和Java11。

Java8是经典的LTS版本,性能优异,系统稳定,良好地支持多种CPU体系结构和操作系统平台。 Java11是新的长期支持版,性能更高,支持更多新功能,经过几年的维护非常稳定。 一些公司在开发环境中使用OracleJDK,在生产环境中使用OpenJDK,而另一些公司在开发环境中使用OpenJDK,在生产环境中使用OracleJDK,或者使用相同的软件包版本。

开发和导入时进行测试就没问题了。

一般来说。 测试和在线预配置的JDK配置必须与生产环境匹配。

什么是Java字节码? Java字节码是编译值Java源代码的中间代码格式,通常称为字节码文件。

2.1字节码文件包含什么? 字节码文件一般包含以下部分:

关于与版本信息静态常量池(符号常量)类的信息字段有关的信息方法的信息调试的信息,可以说大部分信息都由常量池中的符号常量表示。

2.2什么是常数? 常数是不变的量,例如字母“a”或数字1024即使与UTF8编码所对应的二进制格式相对应也不变。 同样,字符串在Java中的二进制表示形式也与“AA”相同。

Java需要注意的是f

inal 关键字修饰的字段和变量,表示最终变量,只能赋值1次,不允许再次修改,由编译器和执行引擎共同保证。

2.3 怎么理解常量池?

在Java中,常量池包括两层含义:

静态常量池,class文件中的一个部分,里面保存的是类相关的各种符号常量。运行时常量池, 其内容主要由静态常量池解析得到,但也可以由程序添加。 3. JVM的运行时数据区有哪些?

根据 JVM规范,标准的JVM运行时数据区包括以下部分:

程序计数器Java虚拟机栈堆内存方法区运行时常量池本地方法栈

具体的JVM实现可根据实际情况进行优化或者合并,满足规范的要求即可。

3.1 什么是堆内存?

  堆内存是指由程序代码自由分配的内存,与栈内存作区分。在Java中,堆内存主要用于分配对象的存储空间,只要拿到对象引用,所有线程都可以访问堆内存。

3.2 堆内存包括哪些部分?

以Hotspot为例,堆内存(HEAP)主要由GC模块进行分配和管理, 可分为以下部分:

背后的天空代存活区老年代

其中,背后的天空代和存活区一般称为年轻代。

3.3 什么是非堆内存?

除堆内存之外,JVM的内存池还包括非堆(NON_HEAP),对应于JVM规范中的方法区,常量池等部分:

MetaSpaceCodeCacheCompressed Class Space 4. 什么是内存溢出?

内存溢出(OOM)是指可用内存不足。

  程序运行需要使用的内存超出最大可用值,如果不进行处理就会影响到其他进程,所以现在操作系统的处理办法是:只要超出立即报错,比如抛出内存溢出错误

  就像杯子装不下,满了要溢出来一样,比如一个杯子只有500ml的容量,却倒进去600ml,于是水就溢出造成破坏。

4.1 什么是内存泄漏?

  内存泄漏(Memory Leak)是指本来无用的对象却继续占用内存,没有再恰当的时机释放占用的内存。

  不使用的内存,却没有被释放,称为内存泄漏 。 也就是该释放的没释放,该回收的没回收。

  比较典型的场景是: 每一个请求进来,或者每一次操作处理,都分配了内存,却有一部分不能回收(或未释放),那么随着处理的请求越来越多,内存泄漏也就越来越严重。

  在Java中一般是指无用的对象却因为错误的引用关系,不能被GC回收清理。

4.2 内存泄漏和内存溢出有什么关系?

  如果存在严重的内存泄漏问题,随着时间的推移,则必然会引起内存溢出。

  内存泄漏一般是资源管理问题和程序BUG,内存溢出则是内存空间不足和内存泄漏的最终结果。

5. 分析对象的内存占用

在64位的系统中,如下:

public class Test{ private long orderId; private long userId; private byte state; private long createMillis;}

一般来说,Test 类的每个对象会占用40个字节。怎么算的,往下看

5.1 对象内存占用计算出来的?

  64位JVM中,对象头占用12字节,但是以8字节对齐,所以一个空类的实例(空对象)至少占用16字节。在32位JVM中,对象头占用8个字节,以4的倍数对齐(不是说4字节)。所以new出来的很多简单对象,甚至是new Object(),都会占用不少内容。

计算方式为:

对象头占用12字节。每个long类型的字段占用8字节,3个long字段占用24字节。byte 字段占用1个字节。以上合计 37字节,而64位JVM是8字节对齐,则实际占用40个字节。 5.2 对象头中包含哪些部分?

对象头中一般包含两个部分:

标记字,占用一个机器字,也就是8字节。类型指针,占用一个机器字,也就是8个字节。通常在32位JVM,以及内存小于-Xmx32G的64位JVM上(默认开启指针压缩),一个引用占用的内存默认是4个字节。所以,64位的JVM一般需要消耗更多堆内存。

所以前面的计算中,对象头占用12字节。

如果是数组,对象头中还会多出一个部分:

数组长度, int值,占用4字节。

如果是包装类型,那么比原生数据类型消耗的内存要多:

Integer:占用16字节(头部8+4=12,数据4字节),因为 int 部分占4个字节,所以使用 Integer 比原生类型int 要多消耗 300% 的内存。Long:一般占用24个字节(头部8+4+数据长度8字节=20字节,再对齐),当然,对象的实际大小由底层平台的内存对齐确定,具体由特定 CPU平台的 JVM 实现决定。 看起来一个 Long 类型的对象,比起原生类型 long 多占用了8个字节(也多消耗200%)。 6. 常用的JVM启动参数有哪些?

截止目前,JVM可配置参数已经达到1000多个,其中GC和内存配置相关的JVM参数就有600多个。
但在绝大部分业务场景下,常用的JVM配置参数也就10来个。
例如:

# JVM启动参数不换行# 设置堆内存 ‐Xmx4g ‐Xms4g # 指定GC算法 ‐XX:+UseG1GC ‐XX:MaxGCPauseMillis=50 # 指定GC并行线程数 ‐XX:ParallelGCThreads=4 # 打印GC日志 ‐XX:+PrintGCDetails ‐XX:+PrintGCDateStamps # 指定GC日志文件 ‐Xloggc:gc.log # 指定Meta区的最大值 ‐XX:MaxMetaspaceSize=2g # 设置单个线程栈的大小 ‐Xss1m # 指定堆内存溢出时自动进行Dump ‐XX:+HeapDumpOnOutOfMemoryError ‐XX:HeapDumpPath=/usr/local/

此外,还有一些常用的属性配置:

# 指定默认的连接超时时间 ‐Dsun.net.client.defaultConnectTimeout=2000‐Dsun.net.client.defaultReadTimeout=2000 # 指定时区 ‐Duser.timezone=GMT+08 # 设置默认的文件编码为UTF‐8 ‐Dfile.encoding=UTF‐8 # 指定随机数熵源(Entropy Source) ‐Djava.security.egd=file:/dev/./urandom 6.1 设置堆内存XMX应该考虑哪些因素?

需要根据系统的配置来确定,要给操作系统和JVM本身留下一定的剩余空间。
推荐配置系统或容器里可用内存的 70­~80% 最好。

6.2 假设物理内存是8G,设置多大堆内存比较合适?

比如说系统有 8G 物理内存,系统自己可能会用掉一点,大概还有 7.5G 可以用,那么建议配置 ‐Xmx6g 。

说明: 7.5G*0.8 = 6G ,如果知道系统里有明确使用堆外内存的地方,还需要进一步降低这个值。

6.3 ‐Xmx 设置的值与JVM进程所占用的内存有什么关系?

JVM总内存=栈+堆+非堆+堆外+Native

6.4 怎样开启GC日志?

一般来说,JDK8及以下版本通过以下参数来开启GC日志:

‐XX:+PrintGCDetails ‐XX:+PrintGCDateStamps ‐Xloggc:gc.log

如果是在JDK9及以上的版本,则格式略有不同:

‐Xlog:gc*=info:file=gc.log:time:filecount=0 6.5 请指定使用G1垃圾收集器来启动 Hello 程序 java ‐XX:+UseG1GC‐Xms4g‐Xmx4g‐Xloggc:gc.log‐XX:+PrintGCDetails‐XX:+PrintGCDateStampsHello 7. Java8默认使用的垃圾收集器是什么?

  Java8版本的Hotspot JVM,默认情况下使用的是并行垃圾收集器(Parallel GC)。其他厂商提供的JDK8基本上也默认使用并行垃圾收集器。

7.1 Java11的默认垃圾收集器是什么?

  Java9之后,官方JDK默认使用的垃圾收集器是G1。

7.2 常见的垃圾收集器有哪些?

常见的垃圾收集器包括:

串行垃圾收集器: ‐XX:+UseSerialGC并行垃圾收集器: ‐XX:+UseParallelGCCMS垃圾收集器: ‐XX:+UseConcMarkSweepGCG1垃圾收集器: ‐XX:+UseG1GC 7.3 什么是串行垃圾收集?

就是只有单个worker线程来执行GC工作。

7.4 什么是并行垃圾收集?

  并行垃圾收集,是指使用多个GC worker 线程并行地执行垃圾收集,能充分利用多核 CPU的能力,缩短垃圾收集的暂停时间。 除了单线程的GC,其他的垃圾收集器,比如 PS,CMS, G1等新的垃圾收集器都使用了多个线程来并行执行GC工作。

7.5 什么是并发垃圾收集器?

  并发垃圾收集器,是指在应用程序在正常执行时,有一部分GC任务,由GC线程在应 用线程一起并发执行。 例如 CMS/G1的各种并发阶段。

7.6 什么是增量式垃圾收集?

  G1的堆内存不再单纯划分为年轻代和老年代,而是划分为多个(通常是 2048 个)可以存放对象的小块堆区域(smaller heap regions)。

  每个小块,可能一会被定义成 Eden 区,一会被指定为 Survivor 区或者 Old 区。 这样划分之后,使得 G1 不必每次都去回收整个堆空间,而是以增量的方式来进行处 理: 每次只处理一部分内存块,称为此次 GC 的回收集(collection set)。

  下一次GC时在本次的基础上,再选定一定的区域来进行回收。增量式垃圾收集的好处 是大大降低了单次GC暂停的时间。

7.7 什么是年轻代?

  年轻代是分来垃圾收集算法中的一个概念,相对于老年代而言,年轻代一般包括:

背后的天空代,Eden区。存活区,执行年轻代GC时,用存活区来保存活下来的对象。 存活区也是年轻代 的一部分,但一般有2个存活区,所以可以来回倒腾。 7.8 什么是GC停顿(GC pause)?

  因为GC过程中,有一部分操作需要等所有应用线程都到达安全点,暂停之后才能执行,这时候就叫做GC停顿,或者叫做GC暂停。

7.9 GC停顿与STW停顿有什么区别?

这两者一般可以认为就是同一个意思。

8. 如果CPU使用率突然飙升,你会怎么排查?

缺乏经验的话,针对当前问题,往往需要使用不同的工具来收集信息,例如:

收集不同的指标(CPU,内存,磁盘IO,网络等等)分析应用日志分析GC日志获取线程转储并分析获取堆转储来进行分析 8.1 如果系统响应变慢,你会怎么排查?

一般根据APM监控来排查应用系统本身的问题。
有时候也可以使用Chrome浏览器等工具来排查外部原因,比如网络问题。

8.2 系统性能一般怎么衡量?

可量化的3个性能指标:

系统容量:比如硬件配置,设计容量;吞吐量:最直观的指标是TPS;响应时间:也就是系统延迟,包括服务端延时和网络延迟。

这些指标。可以具体拓展到单机并发,总体并发,数据量,用户数,预算成本等等。

9. 使用过哪些JVM相关的工具?

这个问题请根据实际情况回答,比如Linux命令,或者JDK提供的工具等。

9.1 查看JVM进程号的命令是什么?

可以使用 ps ‐ef 和 jps ‐v 等等。

9.2 怎么查看剩余内存?

比如: free ‐m , free ‐h , top 命令等等。

9.3 查看线程栈的工具是什么?

一般先使用 jps命令, 再使用 jstack ‐l

9.4 用什么工具来获取堆内存转储?

一般使用 jmap 工具来获取堆内存快照。

9.5 内存Dump时有哪些注意事项?

根据实际情况来看,获取内存快照可能会让系统暂停或阻塞一段时间,根据内存量决定。
使用jmap时,如果指定 live 参数,则会触发一次FullGC,需要注意。

9.6 使用JMAP转储堆内存大致的参数怎么处理?

示例:

jmap ‐dump:format=b,file=3826.hprof 3826 9.7 为什么转储文件以 .hprof 结尾?

JVM有一个内置的分析器叫做HPROF, 堆内存转储文件的格式,最早就是这款工具定义的。

9.8 内存Dump完成之后,用什么工具来分析?

一般使用 Eclipse MAT工具,或者 jhat 工具来处理。

9.9 如果忘记了使用什么参数你一般怎么处理?

  上网搜索是比较笨的办法,但也是一种办法。另外就是,各种JDK工具都支持 ‐h 选项来查看帮助信息,只要用得比较熟练,即使忘记了也很容易根据提示进行操作。


欢迎一键三连~

有问题请留言,大家一起探讨学习

----------------------Talk is cheap, show me the code-----------------------

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。