JVM【八股文】

2023-10-26

JVM【八股文】

JVM内存区域划分

  1. 程序计数器
  2. 方法区

一块大的区域,需要根据功能,来划分不同的小区域。

JVM内存是从操作系统里申请来的,之后堆这部分区域进行了划分。

1.程序计数器

内存中最小的区域,保存了下一条要执行指令的地址~~

指令 => 字节码~

程序要想运行,JVM就得把字节码加载起来,放到内存中,程序就会一条一条把指令从内存中取出来,放到CPU上执行,此时也就需要随时记住,当前执行到哪一条了~

CPU是并发式的执行程序,CPU不是只给你一个进程提供服务。

也正因此,操作系统以线程为单位进行调度,每个线程都得记录自己的执行位置,每个线程就都会有一个程序计数器

2.栈

局部变量 和 方法调用信息

方法调用的时候,每次调用一个新的方法,就会涉及“入栈”操作,每次执行完一个方法,就会涉及到“出栈”操作。

每个线程有一个

3.堆

内存中空间最大的区域

new出来的对象+对象的成员变量 在其中。

一个进程一个堆

多个线程共用一个堆

局部变量在栈上;成员变量和new对象,在堆上。

4.方法区

类对象

方法区的作用:用来存储被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
的。

JVM类加载机制

1.类加载是要干啥?

把.class文件,加载到内存中,构成类对象

在这里插入图片描述

  1. 加载

    先找到对应的 .class文件,然后打开并读取.class文件,同时初步生成一个 类对象

    Loading中的一个关键环节,会把读取并解析到的信息,初步的填写到 类对象中。

  2. 连接

    1. 验证
    2. 准备 ->给静态变量分配内存,并且设置上0值
    3. 解析
  3. 初始化

    真正的对类对象进行初始化,尤其是针对静态成员

2.典型面试题

在这里插入图片描述
在这里插入图片描述

大的原则:

  1. 类加载阶段会进行 静态代码块 的执行。要想创建实例,势必要先进行类加载。
  2. 静态代码块代码块只是在类加载阶段执行一次。
  3. 构造方法和构造代码块,每次实例化都会执行,构造代码块在构造方法前面。
  4. 父类执行在前子类执行在后

在这里插入图片描述

注意:只要这个类被调用到,就会先对这个类进行类加载(实例化、调用方法、调用静态方法、被继承等)

3.关于“双亲委派模型”

它是 类加载 中的一个环节

这个环节处于 Loading 阶段的

  • 双亲委派模型,描述的就是JVM中的类加载器,如何根据类的全限定名(java.lang.String)找到.class文件的过程
  • 类加载器:JVM提供了专门的对象,叫做类加载器,负责进行类加载,当然找到文件的过程也是类加载来负责
  • .class文件,可能放在的位置有好多,有的在JJDK目录中,有的在项目目录中,还有的在其他指定位置,因此JVM里面提供了多个类加载器,每个类加载器负责一个片区
  • 默认的类加载器有三个:
    • (1): 引导类加载器(Bootstrap类加载器)
      它是由本地代码(c/c++)实现的,你根本拿不到他的引用,但是他实际存在,并且加载一些重要的类,它加载(%JAVA_HOME%\jre\lib),如rt.jar(runtime)、i18n.jar等,这些是Java的核心类。 他是用原生代码来实现的,并不继承自 java.lang.ClassLoader。
    • (2): 扩展类加载器(Extension类加载器)
      虽说能拿到,但是我们在实践中很少用到它,它主要加载扩展目录下的jar包, %JAVA_HOME%\lib\ext
    • (3): 系统类加载器(System类加载器)
      它主要加载我们应用程序中的类,如Test,或者用到的第三方包,如jdbc驱动包等。
      这里的父类加载器与类中继承概念要区分,它们在class定义上是没有父子关系的。

双亲委派模型,就是描述这个找目录过程,也就是上述类加载器是如何配合的?

AppClassLoader 在加载一个未知的类名时,它并不是立即去搜寻 Classpath,它会首先将这个类名称交给 ExtensionClassLoader 来加载,如果 ExtensionClassLoader 可以加载,那么 AppClassLoader 就不用麻烦了。否则它就会搜索 Classpath 。

而 ExtensionClassLoader 在加载一个未知的类名时,它也并不是立即搜寻 ext 路径,它会首先将类名称交给 BootstrapClassLoader 来加载,如果 BootstrapClassLoader 可以加载,那么 ExtensionClassLoader 也就不用麻烦了。否则它就会搜索 ext 路径下的 jar 包。

JVM的垃圾回收【重点】

JVM中的垃圾回收机制(GC)

申请内存的时机一般都是明确的(需要保存某个数据,就需要申请内存),

但是释放内存的时间,则是不清楚的。

代码里,创建一个变量(申请一个内存),这个变量啥时候不再使用了?也不是那么容易能确定的

如果内存释放的时机有问题(内存还想要用,结果就被丢了),此时就很难受了

上面是内存释放太早了

要是我迟一点释放行不行呢?就像图书馆,占座~~

所以内存的释放,早了也不行,晚了也不行,需要恰到好处。

垃圾回收的劣势:

  • 消耗额外的开销
  • 可能会影响程序的流畅运行(垃圾回收经常会引入STW问题)

垃圾回收要回收些啥?

  1. 程序计数器:固定大小,不涉及到释放,也就不需要GC
  2. 栈:函数执行完毕,对应的栈帧就自动释放了,也不需要GC
  3. 堆:需要GC,代码中大量的内存都在堆上
  4. 方法区:类对象,类加载来的~~ 进行“类卸载”就需要释放内存,卸载其实是一个非常低频的操作。

垃圾回收具体咋回收?

第一阶段:找垃圾/判断垃圾

    1. 基于引用计数(不是Java)

      简单可靠高效 ,但是有两个致命缺陷!

      • 空间利用率比较低
      • 会有循环引用问题
    2. 基于可达性分析(Java)

      起始位置GCroot

      • 栈上的局部变量
      • 常量池中的引用指向的对象
      • 方法区中的静态成员指向的对象

      优点:

      • 克服了引用计数的两个缺点:空间利用率低,循环引用

      自身缺点:

      • 系统开销大,遍历一次可能比较慢

第二阶段:释放垃圾

明确了谁是垃圾之后,接下来就是回收(释放)垃圾了

回收垃圾(释放垃圾)的三种基本策略:

  1. 标记-清除

    标记就是可达性分析的过程

    此时如果直接放掉,虽然内存还是还给了系统,但是被释放的内存是离散的(不是连续的)

    这个问题非常影响程序的执行

  2. 复制算法

    为了解决内存碎片,引入复制算法

    直接把不是垃圾的,拷贝,把原本的空间整体释放

    此时内存碎片问题迎刃而解

    复制算法的问题:

    • 内存空间利用率低
    • 如果要保留的对象多,要释放的对象少,此时复制的开销很大
  3. 标记-整理

    针对复制算法,再进行改进。

    类似于顺序表删除中间元素

    这个方案空间利用率是高了,但是仍然没有解决复制/搬运元素的开销。

上述方案虽然能解决问题,但是都有缺陷

实际JVM中的实现,会把多种方案结合起来使用~~

分代回收!!

争对对象进行分类(根据对象年龄),一个对象熬过一轮GC扫描,就称涨了一岁

针对不同的年龄的对象,采取不同的方案!!

区域划分:

  1. 新生代
    • 伊甸区
    • 幸存区(两个)
  2. 老年代
  • 刚创建出来的对象在伊甸区。
  • 如果伊甸区的对象熬过一轮GC扫描,就会被拷贝到幸存区。(应用了复制算法)
  • 在后续的几轮GC中,幸存区的对象就在两个幸存区之间来回拷贝(复制算法) 每一轮都会淘汰一波幸存者
  • 持续若干轮之后,对象进入老年代(老年代扫描频率降低)

分代回收中,还有一种情况,有一类对象可以直接进入老年代(大对象,占有内存多的对象)

大对象拷贝开销大,不适用于复制算法

上面 找垃圾 释放垃圾都是算法思想,不是具体落地实现

在JVM中,真正实现上述算法的模块,就是垃圾回收器

  1. Serial回收器:串行回收

    Serial收集器是最基本、历史最悠久的垃圾收集器了。JDK1.3之前回收新生代唯一的选择。

    Serial收集器作为HotSpot中client模式下的默认新生代垃圾收集器。

    Serial收集器采用复制算法、串行回收和"stop-the-World"机制的方式执行内存回收。

    除了年轻代之外,Serial收集器还提供用于执行老年代垃圾收集的Serial Old收集器。Serial Old收集器同样也采用了串行回收和"Stop the World"机制,只不过内存回收算法使用的是标记-压缩算法。

  2. ParNew回收器:并行回收

    ParNew 收集器除了采用并行回收的方式执行内存回收外,两款垃圾收集器之间几乎没有任何区别。ParNew收集器在年轻代中同样也是采用复制算法、"Stop-the-World"机制。

    ParNew 是很多JVM运行在Server模式下新生代的默认垃圾收集器。

  3. Parallel回收器:吞吐量优先

    上述是比较老的来及回收器

  4. CMS回收器:低延迟

    • 初始标记(Initial-Mark)阶段:在这个阶段中,程序中所有的工作线程都将会因为“Stop-the-World”机制而出现短暂的暂停,这个阶段的主要任务仅仅只是标记出GCRoots能直接关联到的对象。一旦标记完成之后就会恢复之前被暂停的所有应用线程。由于直接关联对象比较小,所以这里的速度非常快。
    • 并发标记(Concurrent-Mark)阶段:从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要停顿用户线程,可以与垃圾收集线程一起并发运行。
    • 重新标记(Remark)阶段:由于在并发标记阶段中,程序的工作线程会和垃圾收集线程同时运行或者交叉运行,因此为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间通常会比初始标记阶段稍长一些,但也远比并发标记阶段的时间短。
    • 并发清除(Concurrent-Sweep)阶段:此阶段清理删除掉标记阶段判断的已经死亡的对象,释放内存空间。由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的
  5. G1回收器:区域化分代式

    把整个内存,分成了很小的区域,Region

    给这些Region进行了不同的标记

    有的Region放新生代对象,有的放在老年代(不追求依赖GC就扫描完,分多次来扫)对于业务代码影响更小

重点理解:引用计数+可达性分析+标记清除+标记整理+复制算法+分代回收

重点记忆:Java11开始,垃圾回收器G1.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JVM【八股文】 的相关文章

  • Hibernate中通过ID获取对象

    我注意到我们的高级开发人员使用以下代码通过 ID 检索实体 Override public Source get Long id Session session getSession if session null session sess
  • 使用 ActionBar 选项卡进行导航时菜单会折叠

    我已经使用支持库中的 ActionBar 来将我的应用程序构建为选项卡式导航栏 我的应用程序中有两个选项卡 这两个片段都有菜单 并且有一个菜单项 我想将其显示为操作栏中的一项操作 但由于某种原因 显示了溢出图标 而不是分配给这些项目的图标
  • 如何在java中使用模式匹配器?

    假设字符串是我想提取xyz从字符串中出来 我用了 Pattern titlePattern Pattern compile lttitle gt s s lt title gt Matcher titleMatcher titlePatte
  • 增强的 jsp:include 实现

    一直困扰我的事情之一
  • 如何在jpanel上延迟显示图片?

    这是我遇到问题的代码部分 我应该每 5 秒显示一次图片 但它不起作用 我希望你能帮忙 谢谢 编辑 5秒后所有图片一起显示 JButton btnGenerateNumber new JButton Generate Number btnGe
  • 根本原因 java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

    我有这个小代码用于将我的 jsp 连接到我的 mysql 数据库 String driver com mysql jdbc Driver Class forName driver String url jdbc mysql localhos
  • Java util Logger 未写入文件

    我为我的应用程序编写了一个愚蠢的记录器 它将信息 警告和严重消息写入日志文件 前一段时间它工作得很好 但突然间 它无缘无故地停止工作了 如果日志文件不存在 它会继续创建该文件 但不写入任何内容 我找不到它现在不起作用的原因 我会感谢一些帮助
  • Java Swing - 在运行时动态切换语言环境

    我了解如何国际化 java 程序 但我有一个问题 我的程序中的语言可以随时切换 但我的程序可以存在多种状态 这意味着它可能会也可能不会打开多个 JLabels JPanel JFrame 等 是否有一个类或方法可以将当前的 GUI 更新为切
  • ffmpeg 用于屏幕捕获?

    所以我有一个小程序来捕获屏幕和计算机麦克风的声音 然后屏幕截图被编码为 ScreenVideo2 声音被编码为 AAC 如何使用 ffmpeg 逐帧混合 然后将混合输出发送到 wowza 媒体服务器 如果用ffmpeg无法完成 您能提供一些
  • 将 .cer 格式的证书添加到 .bks 密钥库中

    我需要将 cer 格式的证书添加到 BKS 密钥存储中 SO 上对此进行了描述 如何将 cer 转换为 BKS https stackoverflow com questions 21284466 how to convert cer to
  • Android MediaCodec 在异步模式下比同步模式下慢?

    再次 我有一个关于 Android 的 MediaCodec 类的问题 我已成功解码原始 h264 内容并将结果显示在两个纹理视图中 h264 流来自运行 openGL 场景的服务器 该场景有一个摄像头 因此可以响应用户输入 为了进一步减少
  • 如何使用 RestTemplate 禁用编码

    我正在使用 REST 模板有意在请求 uri 中发送 例如 items a b String responseEntity restTemplate exchange items a b requestObj getHttpMethod r
  • 如何设置按钮的大小?

    我将按钮放在带有 GridLayout 的 JPane 中 然后我用 BoxLayout Y AXIS 将 JPanel 放入另一个 JPanel 中 我希望 GridLayout 中的按钮是方形的 我使用 tmp setSize 30 3
  • 方法链接的优点和缺点以及用对象本身替换所有 void 返回参数的可能性

    我最感兴趣的是Java 但我认为这是一个普遍的问题 最近我一直在使用 Arquillian 框架 ShrinkWrap 使用了大量的方法链 方法链的其他示例是以下方法StringBuilder StringBuffer 使用这种方法有明显的
  • 在JPA、关系型数据库等中,什么是Tuple? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我正在研究 Hibernate 和 JPA 并且一直在寻找这个术语 有人可以用实用和说教的方式向我解释一下这个术语是什么 以及它与 J
  • 如何动态更新属性文件?

    我的应用程序是一个批处理过程 它从 application properties 文件中提取环境变量 我使用的密码必须每隔几个月更新一次 我想自动化密码更新过程并将更新后的密码保存在属性文件中 以便在将来的运行中使用 但我尝试进行的任何更新
  • 如何将java数组列表转换为javascript数组? [复制]

    这个问题在这里已经有答案了 我们如何将 String 对象的 java arraylist 转换为 javascript 数组 这就是我正在做的事情 但我正在寻找更好的方法来做到这一点 我不想迭代数组列表 var myArray
  • 无法查找 Websphere 8.5 中是否启用了 SSL

    我编写了一个简单的 ejb 瘦客户端来查找 IBM WebSphere 8 5 中部署的 bean 当服务器上未启用 SSL 时 我能够成功查找 bean 但是一旦启用 SSL 我就开始收到下面提到的异常 This is how I ena
  • Java Webstart 和 URLConnection 缓存 API

    的描述URLConnection 缓存 API http docs oracle com javase 6 docs technotes guides net http cache html最后一句指出 Java 2 标准版中没有 URLC
  • Java 将函数添加到 json 对象而不使用引号。

    我正在用 java 构建一个 json 对象 我需要将一个函数传递到我的 javascript 中并使用 jquery isFunction 对其进行验证 我遇到的问题是我必须将 json 对象中的函数设置为字符串 但 json 对象将周围

随机推荐

  • QVector用法详细介绍

    QVector类是动态数组的模板类 顺序容器 它将自己的每一个对象存储在连续的内存中 可以使用索引号来快速访问它们 使用前需要包含头文件 include
  • iOS(二)App第一次启动时出现的引导界面

    我们每次打开一个刚刚从AppStore下载下来的软件时 总会出来一个引导界面 有的是宣传产品 有的是介绍App的功能 最后再出来一个按钮正式进入到App 从此以后这个引导界面就再也不会出现了 除非你卸载重装 在查阅相关资料后 做了个简陋的引
  • 逆向爬虫06 bs4,xpath,pyquery实战

    逆向爬虫06 bs4 xpath pyquery实战 原本想要详细的对比一下这三个模块的使用方法 但是在实战的时候发现 只要遵循一个套路 抓取静态网页 即网页信息直接放在html源代码中 就比较容易了 一些使用细节上的问题 每个人遇到的都会
  • Unity Hub、unity、PlasticSCM安装

    目录 一 Unity Hub安装 二 Unity安装 三 PlasticSCM安装 一 Unity Hub安装 第一步 进入官网下载 地址 地址 第二步 安装 跟着提示走就行 二 Unity安装 第一步打开Unity Hub 激活许可证 点
  • 打印机服务器纸张属性不显示,为什么我的打印机能在打印机服务器属性里设置自定义纸张大小,却无法? 爱问知识人...

    问题原因及解决方法 在以往的Windows 98操作系统中 打印机属性里的 纸张大小 中有 自定义 一项 而Windows 2000和Windows XP中自定义的位置是不同于Windows 98的 这里用一个示例来表述 假定用户使用了一款
  • VMware中安装CentOS7

    在VMware中安装CentOS7 01 目录 CentOS7的下载 CentOS7的配置 CentOS7的安装 CentOS7的网络配置 自动获取IP 固定获取IP 02 安装前提 准备工作 提前下载和安装好VMware 下载centos
  • 环境扫描/透射电子显微镜气体样品架的真空压力和微小流量控制解决方案

    摘要 针对环境扫描 透射电子显微镜对样品杆中的真空压力气氛环境和流体流量精密控制控制要求 本文提出了更简单高效和准确的国产化解决方案 解决方案的关键是采用动态平衡法控制真空压力 真空压力控制范围为1E 03Pa 0 7MPa 采用压差法控制
  • Using Java to create customized virtual machine clones on VMWare infrastructure

    Hello Quite a while ago I was given a task to create a java module which would be able to create customized clones from
  • python制作词云图

    准备基础模块 matplotlib 数据可视化模块 numpy 数值计算模块 jieba 分词模块 wordcloud 词云模块 Pillow PIL 图像处理模块 同时准备遮罩图和文本信息 实现代码 导入matplotlib模块pyplo
  • 数据挖掘学习之路二:数据预处理方法概述

    主要是将数据中缺失的数据补充完整 消除噪声数据 识别和删除离群点并解决不一致性 主要达到的目标是 将数据格式标准化 异常数据清除 错误纠正 重复数据清除 A 异常数据处理 分析异常数据 1 使用统计值进行判断 最大值 最小值 平均值等判断是
  • C++中的++i 与 i++详解

    一 区别 i 与 i 的主要区别有两个 1 i 返回原来的值 i 返回加1后的值 2 i 不能作为左值 而 i 可以 二 原理 毫无疑问大家都知道第一点 我们重点说下第二点 首先解释下什么是左值与右值 通俗地说 以赋值符号 为界 左边的就是
  • CUDA小白 - NPP(6) 图像处理 Geometry Transforms (2)

    cuda小白 原始API链接 NPP GPU架构近些年也有不少的变化 具体的可以参考别的博主的介绍 都比较详细 还有一些cuda中的专有名词的含义 可以参考 详解CUDA的Context Stream Warp SM SP Kernel B
  • npm包的发布和删除

    登录npm发布包 1 终端 输入npm login 可以登录npm账号 依次输入用户名 密码 密码盲打 邮箱 2 输入nrm use npm通过命令更改npm服务 需将npm切换为npm官方服务 不能使用taobao镜像 注 可以通过npm
  • 基于虚拟机的集群冗余简化

    为了实现高可用性 企业使用中间软件例如微软和 Veritas 的集群软件 把两台服务器绑定在一个热备环境 即使运行在服务器上的应用程序有集群 感知能力 万一主服务器遭遇硬件或软件错误 这样的安排仍然会导致非应 用程序当机 冗余能消除单点失败
  • 面经——嵌入式软件工程师ARM体系与架构相关

    参考 嵌入式软件工程师笔试面试指南 ARM体系与架构 作者 嵌入式与Linux那些事 发布时间 2021 04 28 15 22 06 网址 https blog csdn net qq 16933601 article details 1
  • Windows下配置nginx+php(wnmp)

    Windows下配置nginx php wnmp waynewuzhenbo 博客园 http www cnblogs com wuzhenbo p 3493518 html Windows下配置nginx php wnmp 第一部分 准备
  • GraphPad Prism 9 for mac/win 安装教程

    GraphPad Prism集生物统计 化学统计 以及科技绘图于一身 其中医学所能用到的绘图需要它几乎都能满足 Prism 现在被各种生物学家以及社会和物理科学家广泛使用 超过110个国家的超过20万名科学家依靠 Prism 来分析 绘制和
  • 删除节点后从新加入的错误

    ERR Node 172 168 63 202 7001 is not empty Either the nodealready knows other nodes check with CLUSTER NODES or contains
  • Qt中绘制直线

    绘制多条直线 直接上代码 绘制直线的部分 QPen pen Qt lightGray 1 pen setStyle Qt DashDotDotLine pen setWidth 1 painter setPen pen painter tr
  • JVM【八股文】

    JVM 八股文 JVM内存区域划分 程序计数器 栈 堆 方法区 一块大的区域 需要根据功能 来划分不同的小区域 JVM内存是从操作系统里申请来的 之后堆这部分区域进行了划分 1 程序计数器 内存中最小的区域 保存了下一条要执行指令的地址 指