JVM知识总汇(JVM面试题篇5.1)

 个人理解,所学有限,若有不当,还请指出

1.JVM是由哪些部分组成,运行流程是什么?

        JVM为java虚拟机,是java程序的运行环境(其实是java字节码文件的运行环境),能够实现一次编写,到处运行,并且拥有垃圾回收机制

JVM是由1.类装载子系统2.运行时数据区3.字节码执行引擎4.本地方法调用四个大部分组成。

运行流程是: java文件在经过javac的命令之后变成了字节码文件,此时jvm启动,类装载子系统将字节码文件加载到了jvm中,然后经过运行时数据区,把字节码加载到内存中,而字节码文 件只是JVM的一套指令集规范,并不能直接交给底层系统去执行,而是通过执行引擎运行,而后执行引擎将字节码翻译为底层系统指令,再交由CPU 执行去执行,以此来实现整个程序的功能。

2.什么是程序计数器?

程序计数器是用来记录下一条代码(字节码)的地址的。(个人理解)因为多线程机制,一个程序在运行时,可能半路上就去执行另一个线程了,若是另一个线程执行完之后呢,就可以通过程序计数器记录的地址,继续执行上一个线程的代码,而不用重新开始,这样能大大提高执行效率。

(资料理解)java虚拟机对于多线程是通过线程轮流切换并且分配线程执行时间。在任何的 一个时间点上,一个处理器只会处理执行一个线程,如果当前被执行的这个线程 它所分配的执行时间用完了【挂起】。处理器会切换到另外的一个线程上来进行 执行。并且这个线程的执行时间用完了,接着处理器就会又来执行被挂起的这个 线程。 那么现在有一个问题就是,当前处理器如何能够知道,对于这个被挂起的线 程,它上一次执行到了哪里?那么这时就需要从程序计数器中来回去到当前的这 个线程他上一次执行的行号,然后接着继续向下执行。 程序计数器是JVM规范中唯一一个没有规定出现OOM的区域,所以这个空间也 不会进行GC。

3.你能给我详细的介绍Java堆吗?

这里先说明一下jvm中的堆在哪里。。。运行时数据区分为多个部分组成:堆,栈,本地方法栈,方法区/元空间,程序计数器五个内存区域组成。   而java堆就是用来存储数组和对象实例的地方,那些new出来的对象都是放到这里的。java堆的内部呢根据分代模型分为年轻代和老年代(比例为1:2)两个部分,其中年轻代又分为三个部分(eden,s0,s1(这里的s0和s1统称为survivor)(此处占比为8:1:1))

4.能不能解释一下方法区?

(个人总结:其中放置的是常量,静态变量,类信息这些)包含class{类信息}(,classloader{加载类},)运行时常量池

  • 常量池可以看作是一张表,虚拟机指令根据这张常量表找到要执行的类名,方法名,参数类型,字面量等信息
5.什么是虚拟机栈?

栈又叫线程栈,每一个线程运行时所需要的内存空间即为栈,(因为其先进后出的特定而得),

每个栈由多个栈帧(frame)组成,对应着每次方法调用时所占用的内存,从mian方法进入之后,开辟了一块mian方法的栈帧区域,而后运行到其他方法的时候就会开辟出另一块栈帧区域用于运行该方法,因此mian方法最先开始,最后结束。每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法。

6.垃圾回收是否涉及栈内存?

JVM中的垃圾回收主要是指在堆中发生的gc操作,垃圾回收涉及堆内存,不涉及栈内存,运行时,当栈帧弹栈之后,内存就会被释放。

7.栈内存分配越大越好吗?

一般栈内存分配1024k,并不是越多越好,栈帧内存越大,可活动的线程就会越少。

8.方法内的局部变量是否线程安全?

如果局部变量没有离开方法的作用区域就是线程安全的,如果是局部变量引用了对象,并逃离方法的作用范围,需要考虑线程安全

9.你听过直接内存吗?

直接内存并不属于内存结构,并不由jvm进行管理,是虚拟机的系统内存,常见于NIO操作时,用于数据缓冲区,它分配回收成本较高,但是读写性能高

10.堆栈的区别是什么?

1.存储对象不同:堆存储数组和对象实例,栈存储方法调用和局部变量。

2.堆拥有垃圾回收机制,而栈没有

3.堆是线程公有的,栈是线程私有的

11.什么是类加载器,类加载器有哪些?

类加载器,(类装载子系统)将字节码 文件加载到JVM中,从而让Java程序能够启动起来。除此之外,类加载器还会负责加载程序所需要的资源。

类加载器的种类:启动类加载器(用于加载 JAVA_HOME/jre/lib目录下的类库),扩展类加载器(要加载JAVA_HOME/jre/lib/ext目录中的类 库),应用类加载器(用于加载开发者自己的类),自定义类加载器(实现自定义类加载规则(摆脱双亲委派的方法))。

12.什么是双亲委派模型?

(个人理解)双亲委派模型是发生在类加载子系统中的,在加载类的时候,经过应用类加载器,扩展类加载器,启动类加载器,在加载一个类的时候会先将类委托给目前类加载器的上级,如果上级加载器有这个类,就由上级加载器进行加载,如果上级的上级有就让其加载,如果都没有再由目前类加载器加载

(资料回答)如果一个类加载器在接到加载类的请求时,它首先不会自己尝试去加载这个类, 而是把这个请求任务委托给父类加载器去完成,依次递归,如果父类加载器可以 完成类加载任务,就返回成功;只有父类加载器无法完成此加载任务时,才由下 一级去加载。

13.JVM为什么采用双亲委派机制?

避免类的重复加载,当父类已经加载后则无 需重复加载,保证唯一性,避免API被恶意修改

14.说一下类装载的执行过程?

类从加载到虚拟机中开始,直到卸载为止,它的整个生命周期包括了:加载、验 证、准备、解析、初始化、使用和卸载这7个阶段。其中,验证、准备和解析这 三个部分统称为连接(linking)

加载:查找和导入class文件。验证:保证加载类的准确性。准备:为类变量分配内存并且设置类变量初始值。解析:把类中的符号引用转换为直接引用。初始化:对类的静态变量,静态代码块进行初始化操作。使用:JVM开始从入口方法开始执行用户的程序代码。卸载:当用户程序执行完毕之后,HVM便开始销毁创建的Class对象。

15.简述Java垃圾回收机制?(GC是什么?为什么要GC)

为了让程序员更专注于代码的实现,而不用过多的考虑内存释放的问题,所以, 在Java语言中,有了自动的垃圾回收机制,也就是我们熟悉的GC

(除了Java语言之外,C#、Python等语言也都有自动的垃圾回收机制)

16.对象什么时候可以被垃圾器回收?

如果要确定一个对象是否是垃圾对象一般有两种方式:

1.引用计数法:一个对象被引用了一次,在当前的对象头上递增一次引用次数,如果这个对象的 引用次数为0,代表这个对象可回收,但是当对象间出现了循环引用的话,则引用计数法就会失效(所以这个方法其实也不太行)

优点: 1.实时性较高,无需等到内存不够的时候,才开始回收,运行时根据对象的计 数器是否为0,就可以直接回收。2. 在垃圾回收过程中,应用无需挂起。如果申请内存时,内存不足,则立刻报 OOM错误。3. 区域性,更新对象的计数器时,只是影响到该对象,不会扫描全部对象。

缺点:1. 每次对象被引用时,都需要去更新计数器,有一点时间开销。 2.浪费CPU资源,即使内存够用,仍然在运行时进行计数器的统计。3. 无法解决循环引用问题,会引发内存泄露。(最大的缺点

2.可达性分析算法:现在的虚拟机采用的都是通过可达性分析算法来确定哪些内容是垃圾对象。 会存在一个根节点【GC Roots】,引出它下面指向的下一个节点,再以下一个 节点节点开始找出它下面的节点,依次往下类推。直到所有的节点全部遍历完 毕。

17.JVM 垃圾回收算法有哪些?

1.标记清除算法:

标记清除算法,是将垃圾回收分为2个阶段,分别是标记和清除。 1.根据可达性分析算法得出的垃圾进行标记 2.对这些标记为可回收的内容进行垃圾回收

缺点:1.效率较低,标记和清除两个动作都需要遍历所有的对象,并且在GC时,需要 停止应用程序,对于交互性要求比较高的应用而言这个体验是非常差的。 2.(重要)通过标记清除算法清理出来的内存,碎片化较为严重,因为被回收 的对象可能存在于内存的各个角落,所以清理出来的内存是不连贯的。

2.复制算法:

复制算法的核心就是,将原有的内存空间一分为二,每次只用其中的一块, 在垃圾回收时,将正在使用的对象复制到另一个内存空间中,然后将该内存空间 清空,交换两个内存的角色,完成垃圾的回收。 如果内存中的垃圾对象较多,需要复制的对象就较少,这种情况下适合使用该 方式并且效率比较高,反之,则不适合。

优点: 在垃圾对象多的情况下,效率较高 清理后,内存无碎片 缺点: 分配的2块内存空间,在同一个时刻,只能使用一半,内存使用率较低

3.标记整理算法:

标记压缩算法是在标记清除算法的基础之上,做了优化改进的算法。和标记清 除算法一样,也是从根节点开始,对对象的引用进行标记,在清理阶段,并不是 简单的直接清理可回收对象,而是将存活对象都向内存另一端移动,然后清理边 界以外的垃圾,从而解决了碎片化的问题

优缺点同标记清除算法,解决了标记清除算法的碎片化的问题,同时,标记压缩 算法多了一步,对象移动内存位置的步骤,其效率也有有一定的影响。 与复制算法对比:复制算法标记完就复制,但标记整理算法得等把所有存活对象 都标记完毕,再进行整理

4.分代收集算法:

在java8时,堆被分为了两份:新生代和老年代,它们默认空间占用比例是 1:2 对于新生代,内部又被分为了三个区域。Eden区,S0区,S1区默认空间占用 比例是8:1:1 具体的工作机制是有些情况: 1)当创建一个对象的时候,那么这个对象会被分配在新生代的Eden区。当 Eden区要满了时候,触发YoungGC。 2)当进行YoungGC后,此时在Eden区存活的对象被移动到S0区,并且当前 对象的年龄会加1,清空Eden区。 3)当再一次触发YoungGC的时候,会把Eden区中存活下来的对象和S0中的 对象,移动到S1区中,这些对象的年龄会加1,清空Eden区和S0区。 4)当再一次触发YoungGC的时候,会把Eden区中存活下来的对象和S1中的 对象,移动到S0区中,这些对象的年龄会加1,清空Eden区和S1区。 5)对象的年龄达到了某一个限定的值(默认15岁 ),那么这个对象就会进 入到老年代中。 当然也有特殊情况,如果进入Eden区的是一个大对象,在触发YoungGC的时 候,会直接存放到老年代。当老年代满了之后,触发FullGC。FullGC同时回收新生代和老年代,当前只 会存在一个FullGC的线程进行执行,其他的线程全部会被挂起。 我们在程序 中要尽量避免FullGC的出现

18.简述分代收集算法。

在java8时,堆被分为了两份:新生代和老年代【1:2】,在java7时,还存在一 个永久代

对于新生代,内部又被分为了三个区域。Eden区,S0区,S1区【8:1:1】 当对新生代产生GC:MinorGC【young GC】 当对老年代代产生GC:Major GC 当对新生代和老年代产生FullGC: 新生代 + 老年代完整垃圾回收,暂停时间长, 应尽力避免

1.新创建的对象,都会先分配到eden区,2.如果eden区没有空间了就会发生minor gc操作,幸存的对象就会进入幸存区

3.当幸存区对象熬过几次回收(最多15次),晋升到老年代(幸存区内存不足 或大对象会导致提前晋升)

19.MinorGC、 Mixed GC 、 FullGC的区别是什么?

MinorGC【young GC】发生在新生代的垃圾回收,暂停时间短(STW)

Mixed GC 新生代 + 老年代部分区域的垃圾回收,G1 收集器特有

FullGC: 新生代 + 老年代完整垃圾回收,暂停时间长(STW),应尽力避免

(STW:暂停所有应用程序线程,等待垃圾回收的完成,进行JVM目的就是要减少STW的发生)

20.说一下 JVM 有哪些垃圾回收器?

串行垃圾收集器

并行垃圾收集器

CMS(并发)垃圾收集器

G1垃圾收集器

串行垃圾收集器:Serial和Serial Old串行垃圾收集器,是指使用单线程进行垃圾回收,堆内存较 小,适合个人电脑 Serial 作用于新生代,采用复制算法 Serial Old 作用于老年代,采用标记-整理算法 垃圾回收时,只有一个线程在工作,并且java应用中的所有线程都要暂停 (STW),等待垃圾回收的完成。

并行垃圾收集器:Parallel New和Parallel Old是一个并行垃圾回收器,JDK8默认使用此垃圾回收器 Parallel New作用于新生代,采用复制算法 Parallel Old作用于老年代,采用标记-整理算法 垃圾回收时,多个线程在工作,并且java应用中的所有线程都要暂停(STW), 等待垃圾回收的完成。

CMS(并发)垃圾收集器:CMS全称 Concurrent Mark Sweep,是一款并发的、使用标记-清除算法的垃圾回 收器,该回收器是针对老年代垃圾回收的,是一款以获取最短回收停顿时间为目 标的收集器,停顿时间短,用户体验就好。其最大特点是在进行垃圾回收时,应 用仍然能正常运行

G1垃圾回收器(重要):应用于新生代和老年代,在**JDK9之后默认使用G1** 划分成多个区域,每个区域都可以充当 eden,survivor,old, humongous, 其中 humongous 专为大对象准备 采用复制算法 响应时间与吞吐量兼顾 分成三个阶段:新生代回收、并发标记、混合收集 如果并发失败(即回收速度赶不上创建新对象速度),会触发 Full GC。

21.强引用、软引用、弱引用、虚引用的区别?

强引用最为普通的引用方式,表示一个对象处于有用且必须的状态,如果一 个对象具有强引用,则GC并不会回收它。即便堆中内存不足了,宁可出现 OOM,也不会对其进行回收 软引用表示一个对象处于有用且非必须状态,如果一个对象处于软引用,在 内存空间足够的情况下,GC机制并不会回收它,而在内存空间不足时,则会 在OOM异常出现之间对其进行回收。但值得注意的是,因为GC线程优先级较 低,软引用并不会立即被回收。 弱引用表示一个对象处于可能有用且非必须的状态。在GC线程扫描内存区域 时,一旦发现弱引用,就会回收到弱引用相关联的对象。对于弱引用的回 收,无关内存区域是否足够,一旦发现则会被回收。同样的,因为GC线程优 先级较低,所以弱引用也并不是会被立刻回收。 虚引用表示一个对象处于无用的状态。在任何时候都有可能被垃圾回收。虚 引用的使用必须和引用队列Reference Queue联合使用

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

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

相关文章

深入理解Docker容器镜像

深入理解Docker容器镜像 1 容器是什么:特殊的进程 容器其实是一种沙盒技术。顾名思义,沙盒就是能够像一个集装箱一样,把你的应用“装”起来的技术。这样,应用与应用之间,就因为有了边界而不至于相互干扰;而…

Docker高频使用命令

一、Docker常用命令总结 1.镜像命令管理 指令描述ls列出镜像build构建镜像来自Dockerfilehoistory查看历史镜像inspect显示一个或多个镜像的详细信息pull从镜像仓库拉取镜像push推送一个镜像仓库rm移除一个或多个镜像prune一处未使用的镜像,没有被标记或被任何容器…

linux之ssh

SSH远程连接协议 SSH远程管理 定义 SSH(Secure Shell )是一种安全通道协议,主要用来实现字符界面的远程的登录、远程复制等功能。 SSH协议对通信双方的数据传输进行了加密处理,其中包括用户登录时输入的用户口令。因此SSH协议具…

WPF之绑定验证(错误模板使用)

1,前言: 默认情况下,WPF XAML 中使用的绑定并未开启绑定验证,这样导致用户在UI上对绑定的属性进行赋值时即使因不符合规范内部已抛出异常(此情况仅限WPF中的数据绑定操作),也被程序默认忽略&…

《苍穹外卖》前端课程知识点记录

一、VUE基础知识 基于脚手架创建前端工程 1. 环境要求 安装node.js:Node.js安装与配置(详细步骤)_nodejs安装及环境配置-CSDN博客查看node和npm的版本号 安装Vue CLI:Vue.js安装与创建默认项目(详细步骤)…

分享一篇关于AGI的短文:苦涩的教训

学习强化学习之父、加拿大计算机科学家理查德萨顿( Richard S. Sutton )2019年的经典文章《The Bitter Lesson(苦涩的教训)》。 文章指出,过去70年来AI研究走过的最大弯路,就是过于重视人类既有经验和知识&…

探究Android的多分辨率支持以及各种类型图标尺寸大小

术语和概念 屏幕尺寸 屏幕的物理尺寸,以屏幕的对角线长度作为依据(比如 2.8寸, 3.5寸)。 简而言之, Android把所有的屏幕尺寸简化为三大类:大,正常,和小。 程序可以针对这三种尺寸…

Docker部署nginx并且实现https访问

实验环境: 在已有的docker环境和nginx镜像的基础上进行操作 1、生成私钥 (1)openssl genrsa -out key.pem 2048 生成证书签名请求 (CSR) 并自签证书: (2)openssl req -new -x509 -key key.pem -out cert.pem -day…

DDD:根据maven的脚手架archetype生成ddd多模块项目目录结构

随着领域驱动的兴起,很多人都想学习如何进行ddd的项目开发,那ddd的项目结构是怎么样的?又是如何结合SpringBoot呢?那么针对这个问题,笔者使用maven的archetype封装一个相对通用的ddd的项目目录,方便一键生成…

karpathy Let‘s build GPT

1 introduction 按照karpathy的教程,一步步的完成transformer的构建,并在这个过程中,加深对transformer设计的理解。 karpathy推荐在进行网络设计的过程中,同时利用jupyter notebook进行快速测试和python进行主要的网络的构建。 …

STM32标准库SPI通信协议与W25Q64

目录 一、SPI通信 1.SPI通信简介 2.硬件电路 3.移位示意图 4.SPI基本时序图 (1)起始和终止 (2)交换一个字节 模式0: 模式1:​编辑 模式2:​编辑 模式3:​编辑 5.SPI时序 …

初识C语言——第九天

ASCII定义 在 C 语言中,每个字符都对应一个 ASCII 码。ASCII 码是一个字符集,它定义了许多常用的字符对应的数字编码。这些编码可以表示为整数,也可以表示为字符类型。在 C 语言中,字符类型被定义为一个整数类型,它占…

数据仓库实验三:分类规则挖掘实验

目录 一、实验目的二、实验内容和要求三、实验步骤1、创建数据库和表2、决策树分类规则挖掘(1)新建一个 Analysis Services 项目 jueceshu(2)建立数据源视图(3)建立挖掘结构 DST.dmm(4&#xff…

43 单例模式

目录 1.什么是单例模式 2.什么是设计模式 3.特点 4.饿汉和懒汉 5.峨汉实现单例 6.懒汉实现单例 7.懒汉实现单例(线程安全) 8.STL容器是否线程安全 9.智能指针是否线程安全 10.其他常见的锁 11.读者写者问题 1. 什么是单例模式 单例模式是一种经典的&a…

线性数据结构-手写队列-哈希(散列)Hash

什么是hash散列? 哈希表的存在是为了解决能通过O(1)时间复杂度直接索引到指定元素。这是什么意思呢?通过我们使用数组存放元素,都是按照顺序存放的,当需要获取某个元素的时候,则需要对数组进行遍历,获取到指…

【skill】onedrive的烦人问题

Onedrive的迷惑行为 安装Onedrive,如果勾选了同步,会默认把当前用户的数个文件夹(桌面、文档、图片、下载 等等)移动到安装时提示的那个文件夹 查看其中的一个文件的路径: 这样一整,原来的文件收到严重影…

吴恩达2022机器学习专项课程C2(高级学习算法)W1(神经网络):2.1神经元与大脑

目录 神经网络1.初始动机*2.发展历史3.深度学习*4.应用历程 生物神经元1.基本功能2.神经元的互动方式3.信号传递与思维形成4.神经网络的形成 生物神经元简化1.生物神经元的结构2.信号传递过程3.生物学术语与人工神经网络 人工神经元*1.模型简化2.人工神经网络的构建3.计算和输入…

Java与Go: 生产者消费者模型

什么是生产者消费者模型 生产者-消费者模型(也称为生产者-消费者问题)是一种常见的并发编程模型,用于处理多线程或多进程之间的协同工作。该模型涉及两个主要角色:生产者和消费者,一个次要角色:缓冲区。 生…

18 内核开发-内核重点数据结构学习

课程简介: Linux内核开发入门是一门旨在帮助学习者从最基本的知识开始学习Linux内核开发的入门课程。该课程旨在为对Linux内核开发感兴趣的初学者提供一个扎实的基础,让他们能够理解和参与到Linux内核的开发过程中。 课程特点: 1. 入门级别&…

办公数据分析利器:Excel与Power Query透视功能

数据分析利器:Excel与Power Query透视功能 Excel透视表和Power Query透视功能是强大的数据分析工具,它们使用户能够从大量数据中提取有意义的信息和趋势,可用于汇总、分析和可视化大量数据。 本文通过示例演示Power Query透视功能的一个小技…