JVM【八股文】

news2025/7/9 7:01:22

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.

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

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

相关文章

android-加壳加固

title: android-加壳加固 categories: Android tags: [android, 加壳, 加固, 混淆] date: 2022-06-20 18:00:23 comments: false mathjax: true toc: true android-加壳 前篇 Android之Apk加壳 - https://blog.csdn.net/LVXIANGAN/article/details/84956476Android动态加载Dex…

李沐论文精度系列之七:Two-Stream双流网络、I3D

文章目录一、双流网络1.1 前言1.2 网络结构1.3 光流(Optical flow)1.3.1 什么是光流1.3.2 如何利用光流1.3.3 双向光流(Bi-directional optical flow)1.3.4 光流的局限性及和对应的预处理(抽取)方式1.3.5 视频模型测试1.4 实验1.4…

✿✿✿JavaScript基本语法一

目 录 1.js的发展史(闲聊版) 2.浏览器分成两部分:渲染引擎和 JS 引擎 3.js与html的关系以及结合方式 (1)js与html的关系 (2)js与html结合方式 4.JavaScript注释 5.js中的基本数据类型 6.js中的变量 7.运算符(自动类型转…

9.前端笔记-CSS-盒子模型-border和padding

页面布局的三大核心: 盒子模型浮动定位 1、盒子模型 1.1 盒子模型组成 盒子模型本质还是一个盒子,包括边框border、外边距margin、内边距padding和实际内容content 1.1.1 边框border 组成 组成:颜色border-color、边框宽度border-wid…

518. 零钱兑换 II【完全背包:求组合数】

518. 零钱兑换 II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位…

C++11 右值,右值引用,移动构造,移动赋值

目录 一、左值,左值引用,右值,右值引用的相关概念: 1. 什么是左值,什么是左值引用? 2. 什么是右值,什么是右值引用? 3. 右值的属性是右值,右值引用的属性是左值 4. …

棒子老虎鸡-第12届蓝桥杯Scratch选拔赛真题精选

[导读]:超平老师计划推出Scratch蓝桥杯真题解析100讲,这是超平老师解读Scratch蓝桥真题系列的第86讲。 蓝桥杯选拔赛每一届都要举行4~5次,和省赛、国赛相比,题目要简单不少,再加上篇幅有限,因此我精挑细选…

研究生有限元仿真应用中存在的问题与对策

作者:尚晓江 导读:有限元分析软件作为计算工具,在科研和工程领域都有广泛应用,而多数用户是在研究生阶段开始接触和使用这些计算软件的。本文以ANSYS结构分析为例,对现阶段研究生应用有限元分析软件的现状和存在的问题…

无人机设计仿真--在Isight平台上进行的基于CST参数化+Xfoil的无人机翼型优化

作者:Graychen 一、工程背景 翼型的选型和设计是飞行器气动设计中的一项基础性工作,翼型对飞行器的气动性能具有根本性的影响。现在高性能飞行器已不再从翼型库中选择适用翼型后直接使用,而是以现有翼型作为基准翼型进行气动优化&#xff…

java基本语法 下

目录 运算符 运算符:算术运算符 运算符:赋值运算符 运算符:比较运算符 运算符:逻辑运算符 运算符:三元运算符 运算符的优先级 程序流程控制 概念 顺序结构 if-else结构 switch-case结构 循环结构 循环结构…

Unity视差贴图多实现对比和改进

视差贴图多种实现方式对比和改进视差贴图视差映射陡峭视差映射视差遮蔽映射迭代视差映射-kerry视差贴图 参考 与法线贴图相同,可以模拟出物体得深度感,同时它得改进是能够随着视角得偏移显示不同得深度感,使得显示更加真实。 由于采样高度…

代码随想录刷题| 多重背包理论基础、背包问题的总结

目录 多重背包理论基础 多重背包的问题 多重背包的解法 多重背包的代码 背包问题的总结 01背包 完全背包 多重背包 多重背包理论基础 多重背包的问题 有N种物品和一个容量为V 的背包。第i种物品最多有Mi件可用,每件耗费的空间是Ci ,价值是Wi 。…

单身福利专场, Python采集某相亲网站美女数据

前言 嗨喽~大家好呀,这里是魔王呐 ❤ ~! 现在,广大年轻人到了一定年纪,一定会引来父母的念叨 不是让相亲就是让结婚的,与其父母念叨,不如自己找一个 到时候问起来,就说再接触呢~~ 今天我们就来用python…

NestJS学习:使用session实现登录验证

参考 大佬的视频教程:nestjs session案例 大佬的博客地址:小满nestjs(第九章 nestjs Session) 在学习某些知识时如果有大佬的视频教程与文档真的是太爽了,能够学习到好多新知识。 nest后台 session session 是服务…

目标检测算法——3D公共数据集汇总(附下载链接)

>>>深度学习Tricks&#xff0c;第一时间送达<<< &#x1f680;&#x1f680;&#x1f680;近期&#xff0c;小海带在空闲之余&#xff0c;收集整理了一批3D公共数据集供大家参考。 整理不易&#xff0c;小伙伴们记得一键三连喔&#xff01;&#xff01;&…

十个值得珍藏的正则表达式

正则表达式常学常忘&#xff0c;记规则不如记例子&#xff0c;记多不如记精&#xff0c;记例子就记最经典的。下面是本人珍藏的十个有用的正则表达式&#xff0c;不吝分享&#xff0c;以飨读者。 正则表达式要点 小括号&#xff1a;代表分组 中括号&#xff1a;代表集合 大括号…

回归分析(1)-回归分析的基本概念

1.回归方程 由于x是可控的非随机变量&#xff0c; 而Y 是一个与x有关的随机变量&#xff0c;因此&#xff0c;直接研究变量Y与x之间的相关关系是困难的&#xff0e; 如果注意到随机变量Y的数学期望反映了随机变量Y的平均取值&#xff0c;因此&#xff0c; 可考虑研究EY与x之间的…

第六章 支持向量机

6.1 间隔与支持向量 给定一个训练样本集&#xff0c;分类学习最基本的想法就是基于训练集D在样本空间中找到一个划分超平面。但是这个划分超平面也是很多的&#xff0c;如下图所示 直观上应该去找两类样本中最中间的划分超平面&#xff0c;因为该划分超平面对训练样本局部扰动…

与分类有关的一种时序优先现象

(A&#xff0c;B)---2*30*2---(1,0)(0,1) 用网络分类A和B&#xff0c;让A由两张图片组成&#xff08;0&#xff0c;0&#xff09;&#xff08;0&#xff0c;1&#xff09;&#xff0c;让B由两张图片组成&#xff08;1&#xff0c;0&#xff09;&#xff08;0&#xff0c;0&…

(附源码)计算机毕业设计JavaJava毕设项目租车网站

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis Maven Vue 等等组成&#xff0c;B/…