JVM面试连环炮:你准备好迎接挑战了吗?

在Java开发领域,JVM面试一直是一个热门话题。作为一名优秀的开发者,你是否已经准备好迎接这场挑战了呢?今天,我们就来深度解析一下JVM面试的热点问题,帮助你更好地应对面试,一举拿下offer!

1、说一下 JVM 的主要组成部分及其作用?

在这里插入图片描述

JVM包含两个子系统和两个组件,两个子系统为Class loader(类装载)、Execution engine(执行引擎);两个组件为Runtime data area(运行时数据区)、Native Interface(本地接口)。

  • Class loader(类装载):根据给定的全限定名类名(如:java.lang.Object)来装载class文件到 Runtime data area中的method area。
  • Execution engine(执行引擎):执行classes中的指令。
  • Native Interface(本地接口):与native libraries交互,是其它编程语言交互的接口。
  • Runtime data area(运行时数据区域):这就是我们常说的JVM的内存。
作用:

在Java程序的执行过程中,首先会通过编译器将Java源代码转换成一种叫做字节码(Bytecode)的中间形式。这种字节码是一种平台无关的二进制代码,它比Java源代码更接近于机器语言,但仍然包含了一些用于定位和操作数据结构的指令。

然后,类加载器(ClassLoader)会负责将这种字节码加载到内存中。这个过程通常是动态进行的,也就是说,当程序需要使用某个类的时候,类加载器就会将这个类的字节码加载到内存中。这个过程通常发生在Java虚拟机(JVM)的运行时数据区(Runtime Data Area)的方法区内。

需要注意的是,虽然字节码文件是JVM的一套指令集规范,但它并不能直接交给底层操作系统去执行。这是因为不同的操作系统可能对同一组字节码有不同的解释方式,因此需要一个专门的命令解析器执行引擎(Execution Engine)来将字节码翻译成底层系统可以执行的指令。

最后,Java程序中还可以调用其他语言编写的本地库接口(Native Interface),进行一些系统调用或者C函数调用。这种方式可以使Java程序更好地利用底层系统的功能,提高程序的性能和效率。

下面是ava程序运行机制详细说明

Java程序运行机制步骤:

  • 首先利用IDE集成开发工具编写Java源代码,源文件的后缀为.java;
  • 再利用编译器(javac命令)将源代码编译成字节码文件,字节码文件的后缀名为.class;
  • 运行字节码的工作是由解释器(java命令)来完成的。

在这里插入图片描述

从上图中可以观察到,Java文件经过编译器的处理后,被转换成了对应的.class文件。接下来,类加载器会负责将这些.class文件加载到Java虚拟机(JVM)中。

实际上,类的加载过程可以用一句话来概括:类的加载是将类的二进制数据从.class文件中读取出来,并将其放入内存中的运行时数据区的方法区内。然后,在堆区创建一个java.lang.Class对象,用于封装类在方法区内的数据结构。

通过类加载器的作用,JVM能够动态地加载和卸载类,使得程序可以在运行时动态地获取和使用类。这种动态性是Java语言的一大特点,它赋予了程序更高的灵活性和扩展性。

2、说一下JVM运行时数据区?

Java虚拟机在执行Java程序的过程中,会将其管理的内存区域划分为多个不同的数据区域。每个数据区域都有特定的用途,并且它们的创建和销毁时间也不同。

首先,Java虚拟机将内存区域划分为堆(Heap)、方法区(Method Area)和栈(Stack)。

  1. 堆:堆是Java虚拟机所管理的最大的数据区域。它用于存储对象实例以及数组。当创建一个新的对象时,会在堆上分配相应的内存空间。而当一个对象不再被引用时,垃圾回收器会负责将其所占用的内存释放回堆中。堆的大小可以通过JVM的参数进行设置,例如-Xmx和-Xms分别表示最大堆大小和初始堆大小。

  2. 方法区:方法区是用于存储类信息、常量池、静态变量等数据的一块内存区域。它与Java类相关联,因为每个Java类都包含方法区的一份拷贝。方法区的生命周期与Java虚拟机的生命周期一致,因此随着虚拟机进程的启动而存在。

  3. 栈:栈是Java虚拟机用来支持函数调用和方法执行的数据结构。每个线程在创建时都会创建一个独立的栈,其中存储着局部变量、操作数栈和返回地址等信息。栈的特点是后进先出(LIFO),即最后进入栈的元素会最先被取出。栈的生命周期与线程的生命周期一致,因此依赖于线程的启动和结束来建立和销毁。

除了这些主要的数据区域外,Java虚拟机还可能划分其他一些辅助的区域,例如程序计数器(Program Counter Register)和本地方法栈(Native Method Stack)等。这些区域的具体用途和生命周期取决于Java虚拟机的实现和运行环境。

  • 程序计数器(Program Counter Register):当前线程所执行的字节码的行号指示器,字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能,都需要依赖这个计数器来完成;
  • 本地方法栈(Native Method Stack):与虚拟机栈的作用是一样的,只不过虚拟机栈是服务 Java方法的,而本地方法栈是为虚拟机调用 Native 方法服务的;

image.png

3、什么是堆内存?

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

  • 新生代(伊甸园区+幸存者区)
  • 老年代

我们在jvm参数中只要使用-Xms,-Xmx等参数就可以设置堆的大小和最大值,理解jvm的堆还需要知道下面这个公式:
堆内内存 = 新生代+老年代。如下面的图所示:

image.png

在使用堆内内存(on-heap memory)的时候,完全遵守JVM虚拟机的内存管理机制,采用垃圾回收器(GC)统一进行内存管理,GC会在某些特定的时间点进行一次彻底回收,也就是Full GC,GC会对所有分配的堆内内存进行扫描,在这个过程中会对JAVA应用程序的性能造成一定影响,还可能会产生Stop The World。
常见的垃圾回收算法主要有:

  • 引用计数器法(Reference Counting)
  • 标记清除法(Mark-Sweep)
  • 复制算法(Coping)
  • 标记压缩法(Mark-Compact)
  • 分代算法(Generational Collecting)

4、什么是堆外内存?

堆外内存,也常被称为直接内存,是Java虚拟机管理内存的一种方式。与Java虚拟机的堆内存相对应,堆外内存是将内存对象分配在Java虚拟机的堆以外的内存区域。这部分内存并不受Java虚拟机的管理,而是直接由操作系统进行操作和管理。

这种设计的主要优点是能够在一定程度上减少垃圾回收对应用程序造成的影响。因为堆外内存的分配和释放不依赖于Java虚拟机的垃圾回收机制,所以它可以更快速地进行内存的分配和释放,从而提高应用程序的性能。

作为Java开发者,我们经常使用java.nio.DirectByteBuffer类来管理堆外内存。这个类的实例会在对象创建的时候自动分配堆外内存。DirectByteBuffer类提供了一种在Java堆外分配内存的方式,它主要是通过其成员变量unsafe来进行操作的。

5、使用堆外内存的优点

  • 减少了垃圾回收, 因为垃圾回收会暂停其他的工作。
  • 加快了复制的速度,堆内在flush到远程时,会先复制到直接内存(非堆内存),然后在发送;而堆外内存相当于省略掉了这个工作。

6、简述Java垃圾回收机制

在Java编程中,程序员并不需要显式地释放对象的内存,这是由Java虚拟机(JVM)自动完成的。当一个对象不再被任何变量引用时,它就会被视为“垃圾”,并被标记为可回收的内存。然后,JVM会定期运行垃圾回收线程来检查这些垃圾对象,并将它们从内存中清除。

这个垃圾回收线程在JVM中的优先级是低的,这意味着它不会在程序运行过程中频繁地执行。相反,它会在JVM认为合适的时候执行。例如,当JVM的空闲时间超过一定阈值时,或者当堆内存的使用率达到一定限制时,垃圾回收线程就会被触发。

垃圾回收线程的工作过程是这样的:首先,它会扫描所有的对象,找出那些没有被任何其他变量引用的对象。这些对象就被称为“垃圾”。然后,它将这些垃圾对象添加到一个称为“垃圾回收集合”的数据结构中。最后,它会从内存中彻底清除这些垃圾对象,释放它们占用的内存空间。

总的来说,Java程序员不需要担心内存管理问题,因为JVM会自动处理这些问题。这大大简化了编程的复杂性,使得程序员可以更专注于实现具体的功能,而不是管理内存。

7、哪些对象会被存放到老年代?

  • 新生代对象每次经历⼀次minor gc,年龄会加1,当达到年龄阈值(默认为15岁)会直接进⼊老年代;
  • 大对象直接进⼊老年代;
  • 新生代复制算法需要⼀个survivor区进行轮换备份,如果出现大量对象在minor gc后仍然存活的情况时,就需要老年代进行分配担保,让survivor⽆法容纳的对象直接进⼊老年代;
  • 如果在Survivor空间中相同年龄所有对象大⼩的总和大于Survivor空间的⼀半,年龄大于或等于该年龄的对象就可以直接进⼊年⽼代。

8、什么时候触发full gc?

  • 调用System.gc时,系统建议执行Full GC,但是不必然执行
  • 老年代空间不⾜
  • 方法区空间不⾜
  • 通过Minor GC后进入老年代的平均大小大于老年代的可用内存
  • 由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小

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

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

相关文章

文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《考虑低碳需求响应及主从博弈的综合能源系统低碳优化调度》

这个标题涉及到综合能源系统的低碳优化调度,并强调了两个关键方面:低碳需求响应和主从博弈。下面对标题的关键词进行解读: 综合能源系统: 这指的是整合了多种能源形式(例如电力、燃气、可再生能源等)的能源…

鸿蒙开发之@State案例

基于State来创建一个任务管理的案例。 //任务类 class Task {static id: number 1name:string 任务名称Task.idfinished:boolean false }//公共卡片样式 Styles function card() {.width(90%).padding(20).backgroundColor(Color.White).borderRadius(15).shadow({radius…

【深度学习】注意力机制(二)

本文介绍一些注意力机制的实现,包括EA/MHSA/SK/DA/EPSA。 【深度学习】注意力机制(一) 【深度学习】注意力机制(三) 目录 一、EA(External Attention) 二、Multi Head Self Attention 三、…

数据在内存中的存储(浮点型篇)

1.例子:5.5:内存存储为101.1,十分位百分位依次为2的-1次方,2的-2次方,而使用科学计数法可以改写为1.011*2的2次方 2.国际标准公式:-1的D次方*M*2的E次方,x1负0正 3.M在存储时默认整数部分为1&…

C 语言指针学习笔记

C 语言中,指针存储的是变量的内存地址!!! 要彻底理解指针,首先要理解 C 语言中变量的存储本质,也就内存。 内存编址与内存空间 计算机的内存是一块用于存储数据的空间,由一系列连续的存储单元…

Python 反编译Il2Cpp APK

引入 https://github.com/Perfare/Il2CppDumper/ 实现 开源的Ii2Cpp Dumper可以帮助我们将So和globalmetadata.dat文件反编译出 Assembly-CSharp.dll 本博客教程可以帮助我们直接拖入APK反编译出来 调用方式 两种 第一种 拖入后回车运行 第二种 放入运行的根目录下 源码 i…

手动搭建koa+ts项目框架(日志篇)

文章目录 前言一、安装koa-logger二、引入koa-logger并使用总结如有启发,可点赞收藏哟~ 前言 本文基于手动搭建koats项目框架(路由篇)新增日志记录 一、安装koa-logger npm i -S koa-onerror and npm i -D types/koa-logger二、引入koa-lo…

IoTDB JavaAPI

文章目录 使用样例Java使用样例 官方已经给出了相关使用Demo,下载地址为: https://github.com/apache/iotdb 直接拉取相对应版本的源码 使用样例 Java使用样例 代码位置 iotdb/example/session/src/main/java/org/apache/iotdb/SessionExample.java iotdb/exa…

借助 AI 梳理知识:Quivr 帮你打造第二大脑 | 开源日报 No.103

fastlane/fastlane Stars: 37.8k License: MIT fastlane 是一个用于 iOS 和 Android 开发人员自动化繁琐任务的工具,如生成屏幕截图、处理配置文件和发布应用程序。 可以轻松地生成屏幕截图处理证书文件发布应用程序通过命令行快速执行操作 DrKLO/Telegram Sta…

血的教训,BigDecimal踩过的坑

很多人都用过Java的BigDecimal类型,但是很多人都用错了。如果使用不当,可能会造成非常致命的线上问题,因为这涉及到金额等数据的计算精度。 首先说一下,一般对于不需要特别高精度的计算,我们使用double或float类型就可…

【lesson7】数据类型之string类型

文章目录 数据类型分类string类型set类型测试 enum类型测试 string类型的内容查找找所有女生(enum中)找爱好有游泳的人(set中)找到爱好中有足球和篮球的人 数据类型分类 string类型 set类型 说明: set:集…

nrfutil工具安装

准备工作,下载相关安装包 链接:https://pan.baidu.com/s/1LWxhibf8LiP_Cq3sw0kALQ 提取码:2dlc 解压后,分别安装以下安装包 在C盘下创建目录nordic_tools,并将nrfutil复制到刚创建的目录下 环境变量path下添加C:\nor…

【截图版本】Linux常用指令详解

———————————————— 版权声明:本文为CSDN博主「小呆瓜历险记」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/m0_58963318/article/details/134713282

ProroBuf C++笔记

一.什么是protobuf Protocol Buffers是Google的⼀种语⾔⽆关、平台⽆关、可扩展的序列化结构数据的⽅法,它可⽤于(数据)通信协议、数据存储等。Protocol Buffers 类⽐于XML,是⼀种灵活,⾼效,⾃动化机制的结…

51单片机应用从零开始(十一)·数组函数、指针函数

51单片机应用从零开始(九)数组-CSDN博客 51单片机应用从零开始(十)指针-CSDN博客 目录 1. 用数组作函数参数控制流水花样 2. 用指针作函数参数控制 P0 口 8 位 LED 流水点亮 1. 用数组作函数参数控制流水花样 要在51单片机中…

0012Java安卓程序设计-ssm记账app

文章目录 **摘要**目 录系统设计5.1 APP端(用户功能)5.2后端管理员功能模块开发环境 编程技术交流、源码分享、模板分享、网课分享 企鹅🐧裙:776871563 摘要 网络的广泛应用给生活带来了十分的便利。所以把记账管理与现在网络相…

GaussDB数据库语法及gsql入门

一、GaussDB数据库语法入门 之前我们讲了如何连接数据库实例,那连接数据库后如何使用数据库呢?那么我们今天就带大家了解一下GaussDB,以下简称GaussDB的基本语法。 关于如何连接数据库,请戳这里。 学习本节课程之后&#xff0c…

【金华模式】双龙旅游引燃露营设计和文旅产融合新方式

(中国国际教育电视台 黎明)金华双龙风景旅游区位于浙江省金华市北郊的金华山麓,是一处融自然山水、溶洞群景观、科普探险、康体休闲、避暑度假、观光朝圣于一体的景区。旅游区人文积淀深厚,道、儒、释文化兼收并蓄,东汉…

大语言模型有什么意义?亚马逊训练自己的大语言模型有什么用?

近年来,大语言模型的崭露头角引起了广泛的关注,成为科技领域的一项重要突破。而在这个领域的巅峰之上,亚马逊云科技一直致力于推动人工智能的发展。那么,作为一家全球科技巨头,亚马逊为何会如此注重大语言模型的研发与…

Blender学习:走路机器人,骨骼绑定

文章目录 建模骨骼创建骨骼绑定 教程地址:八个案例教程带你从0到1入门blender【已完结】 建模 1 做头:新建立方体,Ctrl2细分并应用,进入编辑模式,删除一半点,然后添加镜像修改器,开启范围限制…