JVM面试基本问题整理

文章目录

  • 1、说下对JVM内存模型的理解
  • 2、运行时常量池的位置
  • 3、常量池和运行时常量池的区别
  • 4、内存溢出和内存泄漏
  • 5、Java 对象大小计算
  • 6、GCROOT都有什么
  • 7、常用的JVM启动参数有哪些
  • 8、TLAB

1、说下对JVM内存模型的理解

在这里插入图片描述
1)线程私有区域

  • 程序计数器(Program Counter Register)
    • 作用:记录当前线程正在执行的字节码指令地址
    • 存储内容:当前线程所执行的字节码指令地址。每个线程都有一个独立的程序计数器,用于线程切换后能恢复正确的执行位置。
  • Java 虚拟机栈(Java Virtual Machine Stack)
    • 作用:管理线程的方法调用和执行。
    • 存储内容:栈帧(Stack Frame),包含局部变量表操作数栈动态链接方法出口等信息。每个方法调用都会创建一个栈帧
  • 本地方法栈(Native Method Stack)
    • 作用:管理本地(Native)方法的调用。
    • 存储内容:与 Java 虚拟机栈类似,但用于本地方法的执行。

2)线程共享区域

  • 堆(Heap)
    • 作用:存储所有对象实例和数组。
    • 存储内容:所有对象实例和数组。堆是垃圾收集的主要区域
  • 方法区(Method Area)
    • 作用:存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。
    • 存储内容:类信息(元数据)、常量池、静态变量、JIT 编译后的代码。
  • 元空间(Metaspace):JDK 8 之后,方法区改为使用本地内存的元空间来存储类元数据。
  • 运行时常量池(Runtime Constant Pool)
    • 作用:存储编译期生成的各种字面量和符号引用。
    • 存储内容:字面量、符号引用。这部分内容是方法区的一部分,但因为其重要性,通常单独列出。JDK 8 及之后挪到了堆中。

2、运行时常量池的位置

  • JDK 7 之前:
    运行时常量池位于永久代中。
    永久代存储类元数据、常量池、静态变量、类方法等。
  • JDK 7:
    运行时常量池从永久代移到了中。
    永久代依然存在,用于存储类元数据和其他信息,但常量池不再存放在永久代中。
  • JDK 8 及之后:
    方法区被移除,取而代之的是元空间(Metaspace)。
    元空间使用本地内存存储类元数据(如类名、方法、字段等),不再受限于堆大小。
    运行时常量池依然位于堆中,不在元空间内。

3、常量池和运行时常量池的区别

常量池和运行时常量池是 Java 中两个相关但不同的概念,它们分别用于不同的阶段和存储不同类型的数据。

1)常量池(Constant Pool)
常量池是在编译期生成的,是 Class 文件的一部分。每个 Class 文件都包含一个常量池,存储了编译期间生成的各种字面量和符号引用。

特点和存储内容

  • 位置:Class 文件中。
  • 存储内容:
    字面量(如整数、浮点数、字符串常量)。
    符号引用(如类名、方法名、字段名、接口方法名)。
    作用:用于支持 Java 虚拟机在类加载时和运行时对这些字面量和符号引用的解析。

2)运行时常量池(Runtime Constant Pool)
运行时常量池是从常量池加载而来的,是每个类或接口在加载后存储在 JVM 内存中的一部分。运行时常量池存在于方法区中(在 JDK 8 之后,方法区被元空间取代,但运行时常量池仍然位于堆内存中)。

特点和存储内容

  • 位置:方法区的一部分(JDK 8 之后为堆内存)。
  • 存储内容:
    从 Class 文件的常量池中加载的字面量和符号引用。
    动态生成的常量(如字符串池中的字符串常量)。
  • 作用:在运行时为 JVM 提供字面量和符号引用的解析与存储支持,允许在运行时添加新的常量。

主要区别:生成时机、位置、内容、作用不同

4、内存溢出和内存泄漏

内存溢出(OutOfMemory)和内存泄漏(Memory Leak)是两种常见的内存管理问题,它们在性质、原因和影响方面有所不同。

1)内存溢出
定义:内存溢出是指程序在运行过程中,申请内存时没有足够的内存可用,导致 JVM 或操作系统抛出内存不足的错误。

原因

  • 堆内存溢出:程序创建了太多对象,导致堆内存耗尽。例如,使用了一个大集合而没有适时清除无用对象。
  • 方法区溢出:加载了过多的类或方法,导致方法区(元空间)耗尽。这在频繁动态生成类的应用(如使用大量代理或反射)中常见。
  • 栈内存溢出:递归调用过深或方法调用栈过大,导致栈内存耗尽。例如,递归没有适时结束。

表现

  • 堆内存溢出:JVM 抛出 java.lang.OutOfMemoryError: Java heap space 错误。
  • 方法区溢出:JVM 抛出 java.lang.OutOfMemoryError: Metaspace(JDK 8 及以后)或 java.lang.OutOfMemoryError: PermGen space(JDK 7 及以前)错误。
  • 栈内存溢出:JVM 抛出 java.lang.StackOverflowError 或 java.lang.OutOfMemoryError: unable to create new native thread 错误。

解决方法

  • 优化代码:避免创建过多的对象,使用更有效的数据结构。
  • 调整 JVM 参数:增加堆内存(-Xmx),增加元空间大小(-XX:MaxMetaspaceSize)。
  • 改进算法:减少递归深度,使用循环替代深度递归。

2)内存泄漏
定义:内存泄漏是指程序在运行过程中,已经不再使用的对象或资源仍然被引用,导致这些对象或资源无法被垃圾收集器回收,逐渐耗尽内存。

原因

  • 长生命周期对象引用短生命周期对象:如静态集合类持有对动态创建对象的引用,导致动态对象不能被回收。
  • 未正确关闭资源:如数据库连接、文件流未关闭。
  • 事件监听和回调:注册的事件监听器或回调未被适时移除,导致对象无法被回收。

表现

  • 内存使用持续增加:应用程序在运行过程中,内存使用持续增加,直至耗尽内存。
  • 性能下降:随着内存使用增加,GC 的频率和时间增加,导致性能下降。

解决方法

  • 检查引用:确保不再使用的对象不再被引用。
  • 及时关闭资源:使用 try-with-resources 语句或在 finally 块中关闭资源。
  • 移除监听器:在不再需要时,移除注册的事件监听器或回调。

总结
内存溢出 vs 内存泄漏

5、Java 对象大小计算

计算 Java 对象的大小涉及对象头、实例数据和对齐填充。以下是具体的计算方法:

1)对象头(Object Header):

  • Mark Word:32 位 JVM 中占 4 字节,64 位 JVM 中占 8 字节。
  • Class Pointer:32 位 JVM 中占 4 字节,64 位 JVM 中占 8 字节(使用压缩指针时为 4 字节)。

2)实例数据(Instance Data):

  • 对象的字段数据。基本类型字段的大小如:int 4 字节,byte 1 字节。引用类型字段在 32 位 JVM 中占 4 字节,64 位 JVM 中占 8 字节(使用压缩指针时为 4 字节)。

3)对齐填充(Padding):

  • 为满足对象大小是 8 字节的倍数,JVM 可能会在对象结尾添加填充字节。

示例:

public class ComplexObject {
    int intField;         // 4 字节
    double doubleField;   // 8 字节
    Object refField;      // 4 字节(压缩指针)
    byte byteField;       // 1 字节
}

计算步骤:

  • 对象头:64 位 JVM 使用压缩指针时为 16 字节(8 字节 Mark Word + 8 字节 Class Pointer)。
  • 实例数据:intField 4 字节,doubleField 8 字节,refField 4 字节,byteField 1 字节。
  • 对齐填充:当前大小为 16 + 4 + 8 + 4 + 1 = 33 字节,需填充 7 字节。
    总大小:16 + 4 + 8 + 4 + 1 + 7 = 40 字节。

⭐️总结

  • 对象头:64 位 JVM 压缩指针时为 16 字节。
  • 实例数据:基本类型按大小分配,引用类型使用压缩指针为 4 字节。
  • 对齐填充:确保总大小为 8 字节的倍数。

6、GCROOT都有什么

在 Java 中,GCROOT(垃圾回收根)是指可以直接或间接引用到活动对象的引用链的起点。GC ROOT 对象是 GC 不会回收的对象,因为它们在程序执行期间仍然可访问。

GC ROOT 可能包括以下几种类型的对象:

静态变量(Static Variables):类的静态变量引用的对象。
本地变量(Local Variables):当前活动线程的栈帧中的局部变量引用的对象。
活动线程(Active Threads):尚未终止的线程引用的对象。
JNI 引用(JNI References):由本地方法(Native Method)引用的 Java 对象。
虚拟机内部引用(JVM Internal References):由虚拟机自身引用的对象,如常量池、类的引用等。

7、常用的JVM启动参数有哪些

JVM (Java虚拟机)的启动参数用于配置和调整Java应用程序的运行时行为。以下是一些常用的JVM启动参数:

  • .-Xmx: 指定Java堆内存的最大限制。例如,-Xmx512m 表示最大堆内存为512兆字节
  • -Xms: 指定Java堆内存的初始大小。例如,-Xms256m 表示初始堆内存为256兆字节
  • -Xss: 指定每个线程的堆栈大小。例如,-Xss256k 表示每个线程的堆栈大小为256千字节。
  • -XX:MaxPermSize (对于Java 7及之前的版本)或-XX:MaxMetaspaceSize(对于Java 8及以后的版本): 指定永久代 ava 7及之前)或元空间 (Java8及以后) 的最大大小。
  • -XX:PermSize(对于Java 7及之前的版本)或 -XXMetaspaceSize (对于Java 8及以后的版本): 指定永久代 Java 7及之前)或元空间 (Java 8及以后) 的初始大小。
  • -Xmn: 指定年轻代的大小。例如,-Xmn256m 表示年轻代大小为256兆字节,
  • -XX:SurivorRatio: 指定年轻代中Eden区与Survivor区的大小此例。例如-XX:SuvivorRatio=8 表示Eden区与每个Surivor区的大小比例为8:1.
  • -XX:NewRatio: 指定年轻代与老年代的大小比例。例如,-XX:NewRatio=2 表示年轻代和老年代的比例为1:2.
  • -XX:MaxGCPauseMilis: 设置垃圾回收的最大暂停时间目标。例如,-XX:MaxGCPauseMilis=100 表示垃圾回收的最大暂信时间目标为100毫秒
  • -XX:ParallelGCThreads: 指定并行垃圾回收线程的数量。例如,-XX:ParallelGCThreads=4 表示使用4个线程进行并行垃圾回收,
  • -XX:+UseConcMarkSweepGC: 启用并发标记清除垃圾回收器。
  • -XX:+UseG1GC: 启用G1 (Garbage First) 垃圾回收器。
  • -Dproperty=value: 设置Java系统属性,可以在应用程序中使用 System.getProperty"property")来获取这些属性的值。这些是一些常见的JM启动参数,可以根据应用程序的需和性能调优的目标进行调整。JVM启动参数的使用可以显著影响应用程序的性能和行为,因此在设置这些参数时需要谨慎。同时,JVM支持的启动参数因不同的JVM版本和供应商而有所不同,建议查阅相关文档以获取更详细的信息。

8、TLAB

Thread Local AllocationBuffer,线程本地分配缓冲区。

1)原理:
在多线程并发情况下,对象的分配会存在竞争,多个线程同时申请内存可能会导致频繁的加锁和解锁操作,从而降低分配效率。TLAB 的出现就是为了解决这个问题。

TLAB 为每个线程分配了一块独立的内存区域,每个线程在自己的 TLAB 区域内进行对象的分配,不再涉及到全局的内存分配锁,从而避免了多线程之间的竞争。

2)TLAB 的优点包括:

  • 降低内存分配竞争:每个线程有自己的 TLAB,避免了多线程之间的内存分配竞争,提高了分配效率。
  • 减少同步开销:减少了因对象分配而引起的同步开销,提高了多线程并发时的性能。
  • 提高缓存局部性:TLAB 中的对象是连续分配的,有利于提高 CPU 缓存的命中率。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

转让无区域商业管理公司挺批行业包变更

无区域的名称我们可以直接进行名称的申请核准。 从新规施行之后,国家局核名批准难度更高。新申请的无区域名称已经停批了,进行核名将更难,而需要满足一定条件并在成立一年后才能变更升级名称。而这个过程并非易事,难度非常高。可以…

微信小程序 画布canvas

属性说明 属性类型默认值必填说明最低版本typestring否指定 canvas 类型,支持 2d (2.9.0) 和 webgl (2.7.0)2.7.0canvas-idstring否canvas 组件的唯一标识符,若指定了 type 则无需再指定该属性1.0.0disable-scrollbooleanfalse否当在 canvas 中移动时且…

第二十讲:文件操作

第二十讲:文件操作 1.什么是文件1.1什么是文件1.1.1程序文件1.1.2数据文件 1.2二进制文件和文本文件数据的存储方式 2.流和标准流2.1流2.2标准流 3.文件指针4.文件的打开与关闭5.文件顺序读写5.1顺序读写函数介绍5.2打开和关闭函数5.2.1fopen函数5.2.2fclose函数 5.…

U盘文件系统结构损坏的应对与预防

在数字化时代,U盘作为便携式存储设备,其重要性不言而喻。然而,当U盘文件系统结构损坏时,我们可能会面临数据丢失的风险。本文将深入探讨U盘文件系统结构损坏的问题,分析其产生的原因,并给出相应的数据恢复方…

零基础入门学用Arduino 第一部分(三)

重要的内容写在前面: 该系列是以up主太极创客的零基础入门学用Arduino教程为基础制作的学习笔记。个人把这个教程学完之后,整体感觉是很好的,如果有条件的可以先学习一些相关课程,学起来会更加轻松,相关课程有数字电路…

深度学习:如何静悄悄地改变我们的日常生活

深度学习 深度学习:如何静悄悄地改变我们的日常生活一、消费电子产品智能手机与个人助理娱乐与社交媒体 二、医疗健康三、汽车与交通四、公共安全五、总结 深度学习:如何静悄悄地改变我们的日常生活 在近年来,深度学习技术因其强大的数据处理…

GO语言 服务发现概述

https://zhuanlan.zhihu.com/p/32027014 明明白白的聊一下什么是服务发现-CSDN博客 一、服务发现 是什么 在传统的系统部署中,服务运行在一个固定的已知的 IP 和端口上,如果一个服务需要调用另外一个服务,可以通过地址直接调用。 但是&…

linux本地搭建dns

不需要图形化界面 使用的是dnsmasq,配置简单 1.安装 deb系列linux apt-get install dnsmasqrhat系列linux yum install dnsmasq2.编辑配置文件 vi /etc/dnsmasq.conf设置主dns服务器,比如现有公用的的114.114.114.114 8.8.8.8这类的 server8.8.8.8…

IEDA集成依赖概述

IEDA集成依赖概述 目录概述需求: 设计思路实现思路分析1.NoSQL Spring Data Redis (AccessDriver)Spring Data Reactive RedisSpring Data MongoDBSpring Data Reactive MongoDBSpring Data for Apache CassandraSpring Data Reactive for Apache CassandraSpring D…

传统工科硕士想转嵌入式,时间够吗?

在开始前刚好我有一些资料,是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!! 零基础开始学&#xff0…

ArcGIS for js 4.x 加载图层

二维&#xff1a; 1、创建vue项目 npm create vitelatest 2、安装ArcGIS JS API依赖包 npm install arcgis/core 3、引入ArcGIS API for JavaScript模块 <script setup> import "arcgis/core/assets/esri/themes/light/main.css"; import Map from arcgis…

本地运行feishu-chatgpt项目结合内网穿透实现无公网IP远程访问

文章目录 前言环境列表1.飞书设置2.克隆feishu-chatgpt项目3.配置config.yaml文件4.运行feishu-chatgpt项目5.安装cpolar内网穿透6.固定公网地址7.机器人权限配置8.创建版本9.创建测试企业10. 机器人测试 前言 本文主要介绍如何在飞书中创建chatGPT机器人并且结合内网穿透工具…

Git+Gitlab 远程库测试学习

Git远程仓库 1、Git远程仓库 何搭建Git远程仓库呢&#xff1f;我们可以借助互联网上提供的一些代码托管服务来实现 Gitee 码云是国内的一个代码托管平台&#xff0c;由于服务器在国内&#xff0c;所以相比于GitHub&#xff0c;码云速度会更快 码云 Gitee - 基于 Git 的代码托…

3D39无人机摇杆电位器食用指南

这个摇杆精度会非常的不错&#xff0c;虚位只在后面有一点&#xff0c;当然价格也比较贵。最便宜某宝上也得 &#xffe5;15 一个。 使用这个摇杆和使用2块钱一个的 PS 写的代码都一样&#xff0c;只是注意下接线上的一些问题就行。 需要注意两个ADC引脚最好不要挨着&#xf…

RK3568笔记三十:PP-ORCv3自训练部署

若该文为原创文章&#xff0c;转载请注明原文出处。 一、介绍 PP-OCR 是百度公布并开源的OCR领域算法&#xff0c;一个轻量级的OCR系统&#xff0c;在实现前沿算法的基础上&#xff0c;考虑精度与速度的平衡&#xff0c; 进行模型瘦身和深度优化&#xff0c;使其尽可能满足产业…

九家大模型“决战”高考!AI作文哪家强?阅卷名师点评来了!

2024.06.07 本文字数&#xff1a;12474&#xff0c;阅读时长大约21分钟 导读&#xff1a;语文老师对AI作文的评价是&#xff0c;“中规中矩&#xff0c;没有‘血肉’&#xff0c;缺一点情感和灵气。” 作者 | 第一财经 刘晓洁 冯小芯 马一凡 吕倩 又到一年高考季&#xff0c;…

单元测试覆盖率

什么是单元测试覆盖率 关于其定义&#xff0c;先来看一下维基百科上的一段描述&#xff1a; 代码覆盖&#xff08;Code coverage&#xff09;是软件测试中的一种度量&#xff0c;描述程序中源代码被测试的比例和程度&#xff0c;所得比例称为代码覆盖率。 简单来理解&#xff…

问题:11单位内部人员对行政机关作出的行政处分不服,可申请行政复议. #其他#微信

问题&#xff1a;11单位内部人员对行政机关作出的行政处分不服,可申请行政复议. 参考答案如图所示

阅读笔记——《AFLNET: A Greybox Fuzzer for Network Protocols》

【参考文献】Pham V T, Bhme M, Roychoudhury A. Aflnet: a greybox fuzzer for network protocols[C]//2020 IEEE 13th International Conference on Software Testing, Validation and Verification (ICST). IEEE, 2020: 460-465.【注】本文仅为作者个人学习笔记&#xff0c;…

JavaSE——抽象类和接口

目录 一 .抽象类 1.抽象类概念 2.抽象类语法 3.抽象类特性 4.抽象类的作用 二. 接口 1.接口的概念 2.语法规则 3.接口的使用 4.接口特性 5.实现多个接口 6.接口间的继承 三.抽象类和接口的区别 一 .抽象类 1.抽象类概念 在面向对象的概念中&#xff0c;所有的对…