JVM 虚拟机面试知识脑图 初高级

news2024/9/29 19:17:41

导图下载地址
https://mm.edrawsoft.cn/mobile-share/index.html?uuid=3f88d904374599-src&share_type=1

类加载器

双亲委派模型

当一个类收到类加载请求,它首先把类加载请求交给父类(如果还有父类,继续往上递交请求).如果父类无法加载该类,再交给子类加载
防止内存中出现多份同样的字节码对象 (出于安全性考虑)
保证核心.class不被篡改

如何打破双亲委派模型

1.自定义类加载器,重写loadClass方法
2.使用上下文类加载器

打破双亲委派模型的案例

Tomcat
JDBC

类加载器

应用程序类加载器 AppClassLoader
使用java语言编写
加载范围
负责加载环境变量classpath或系统属性java.class.path指定的类库
自己写的类都是由应用程序加载类加载的
扩展类加载器 ExtClassLoader
使用java语言编写
加载范围
从java.ext.dirs指定的路径下加载类库;或者从JDK安装目录的jre/lib/ext目录下加载类库
如果用户自定义的jar包放在jre/lib/ext下,也会自动由扩展类加载器加载
引导类加载器 BootStrapClassLoader
引导类加载器使用C/C++语言实现,在JVM内部
加载范围
用于加载核心库
只加载包名为java,javax,sun开头的类

JVM组成

存在线程安全问题

方法区(永久代)
方法区是所有线程共享的区域.用于存储被Java虚拟机加载的类信息,常量,静态变量,即时编译后的数据
即时编译: 为了平衡启动和执行的效率,JVM结合解释执行和编译执行的特点,进行解释执行并对热点代码进行编译优化,这样的执行过程叫即时编译
当方法区无法满足内存分配需求时,抛出OutOfMemoryError异常
1.8之后叫元空间,使用物理内存,不受jvm参数限制
堆是虚拟机管理中内存最大的一块,被所有线程共享.所有对象实例以及数组都要在堆上分配内存
堆是垃圾管理器管理的的主要区域,因此也被称为"GC堆"
GC : 这里指Java的垃圾回收机制
常量池1.8在堆中
分为新生代,老年代 内存大小比例为 1: 2

新生代又分为Eden和Survivor (From与To,这里简称一个区)两个区。加上老年代就这三个区。数据会首先分配到Eden区当中(当然也有特殊情况,如果是大对象那么会直接放入到老年代(大对象是指需要大量连续内存空间的java对象)。当Eden没有足够空间的时候就会触发jvm发起一次Minor GC,。如果对象经过一次Minor-GC还存活,并且又能被Survivor空间接受,那么将被移动到Survivor空间当中。并将其年龄设为1,对象在Survivor每熬过一次Minor GC,年龄就加1,当年龄达到一定的程度(默认为15)时,就会被晋升到老年代中了,当然晋升老年代的年龄是可以设置的。

新生代
  • 一个 Eden 区
  • 两个 survival 区 ( From Survivor、To Survivor ),无论什么时候总有一块 survival 是空闲的
  • 为什么需要两个 survival 区设置两个Survivor区最大的好处就是解决了碎片化
老年代( 垃圾回收后在 survival区存活 15 (默认) 次后进入 ) , 在老年代一般使用 标记-清除算法 或者 标记整理算法
为什么要这么分代 : 可以根据各个代的特点进行对象分区存储,更便于回收,采用最适当的收集算法
新生代中,每次垃圾收集时都发现大批对象死去,只有少量对象存活,便采用了复制算法,只需要付出少量存活对象的复制成本就可以完成收集。
而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须采用“标记-清理”或者“标记-整理”算法。

线程私有

本地方法区
本地方法栈中就是C和C++的代码编译的方法
程序计数器
保存当前线程所正在执行的字节码指令的地址(行号)
栈是线程私有的,每个方法在执行的时候都会创建一个栈帧,方法先进后出
栈帧
  • 操作数栈操作数栈可理解为java虚拟机栈中的一个用于计算的临时数据存储区。
  • 局部变量表存放局部临时数据
  • 动态链接在程序运行期间将符号引用转为直接引用
  • 出口方法执行完毕返回的位置
JVM会为每一个线程分配一个栈帧

JVM抛出错误

OutOfMemoryError 内存溢出

出现的原因
不断创建对象,并添加到集合中,无法被回收,抛出内存溢出错误
扩展栈的时候申请不到足够的空间,抛出内存溢出错误
修改最小内存和最大内存
-Xms -Xmx

StackOverflowError 栈深度过大

递归调用方法无出口

JVM的GC垃圾回收机制

什么是GC垃圾回收机制

在系统运行过程中,会产生一些无用的对象,这些对象一直占着内存,如果不对这些对象进行清除,会导致内存资源耗尽. 所以就需要GC垃圾回收机制 回收 堆 和 方法区的内存

判断对象是否存活

引用计数法
每个对象在创建的时候,就给这个对象绑定一个计数器。每当有一个引用指向该对象时,计数器加一;每当有一个指向它的引用被删除时,计数器减一。这样,当没有引用指向该对象时,计数器为0就代表该对象死亡
引用计数法就是如果一个对象没有被任何引用指向,则可视之为垃圾。这种方法的缺点就是不能检测到环的存在
优点
引用计数算法的实现简单,判定效率也很高
缺点
不能解决循环依赖问题,所以一般不用
可达性分析法
)
优点
能解决引用计数法的循环依赖问题
缺点
和引用计数法比没有缺点

三种 GC垃圾回收机制

Minor GC
发生在新生代的垃圾回收,最频繁,速度最快
当eden区满时,触发Minor GC .当为一个对象申请内存地址时,发现eben区内存不够用就发生Minor GC
Major GC
发生在老年代的垃圾回收,通常会伴随着Minor GC ,Major GC通常伴随着 Minor GC 速度比 Minor GC慢
晋升到老年代的对象大于老年代剩余的空间内存
永久代空间不足
手动执行System.gc
MinorGC后存活的对象超过了老年代剩余空间
方法区空间不足
Full GC
清理整个堆空间,包括方法区
老年代被写满
持久代被写满
System.gc()被显示调用
会产生 STW ( stop the world ) 整个世界都停了 所以应该极力避免 Full GC

垃圾回收算法(GC回收算法)

标记-清除算法
创建对象的时候储存一个标记位,记录对象的状态(是死是活)
优点:可以解决相互循环引用问题,必要时才进行回收
缺点:标记和清除效率不高,回收时应用需要挂起,.且会造成内存碎片问题
内存碎片 : 内存中的存储空间不连续,当需要申请连续的存储空间时无法申请到
标记整理算法
创建对象的时候储存一个标记位,记录对象的状态(是死是活),但一阶段不进行对象删除,还要进行二阶段,在二阶段将存活的对象整理起来,放到另一端空间,然后再把剩下的对象全部清除
优点:解决了标记-清除算法造成的内存碎片问题
缺点:由于在二阶段移动了对象,所以需要去更新引用
复制算法
将内存平均分为两份,每次只使用其中一部分,当这部分内存满的时候,将其中存活的内存复制到另一半内存空间,然后将这部分内存清空,再去使用另一半内存空间.循环下去
复制算法与标记整理算法的区别在于 该算法不是在同一个区域复制,而是将所有存活的对象复制到另一个区域内
优点: 在存活对象不多的情况下,性能高,能解决内存碎片和java垃圾回收算法之-标记清除 中导致的引用更新问题。
缺点 : 会造成一部分的内存浪费。不过可以根据实际情况,将内存块大小比例适当调整;如果存活对象的数量比较大,复制算法的性能会变得很差
分代算法 ( JVM 使用 )
新生代对象朝生夕死,对象数量多,只要重点扫描这个区域,那么就可以大大提高垃圾收集的效率。另外老年代对象存储久,无需经常扫描老年代,避免扫描导致的开销。
新生代
在新生代,每次垃圾收集器都发现有大批对象死去,只有少量存活,采用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。
老年代
而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须“标记清除法或者标记整理算法进行回收

垃圾收集器

JAVA中的引用

强引用

最普遍的引用方式,当内存不足时,JVM宁愿抛出OOM异常,也不会回收强引用的对象

软引用

有用但是不是必须的对象,当JVM内存不足时会回收该对象
在Java中用java.lang.ref.SoftReference类来表示
在实际程序设计中一般很少使用弱引用与虚引用,使用软引用的情况较多,这是因为软引用可以加速JVM对垃圾内存的回收速度,可以维护系统的运行安全,防止内存溢出(OutOfMemory)等问题的产生
利用软引用和弱引用解决OOM问题:假如有一个应用需要读取大量的本地图片,如果每次读取图片都从硬盘读取,则会严重影响性能,但是如果全部加载到内存当中,又有可能造成内存溢出,此时使用软引用可以解决这个问题。
设计思路是:用一个HashMap来保存图片的路径和相应图片对象关联的软引用之间的映射关系,在内存不足时,JVM会自动回收这些缓存图片对象所占用的空间,从而有效地避免了OOM的问题。

弱引用

非必须对象,进行GC的时候就会回收该对象
在java中,用java.lang.ref.WeakReference类来表示

虚引用

如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。虚引用主要用来跟踪对象被垃圾回收的活动
在java中用java.lang.ref.PhantomReference类表示

Eden 区 与 survival 区 内存大小占比 默认 为 8 : 1 : 1 ,通常在新生代使用复制算法

Major GC 和 Full GC 通常是等价的

一般用于老年代回收

一般用于老年代

一般用于新生代的Eden 区和 survival 区

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

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

相关文章

[LeetCode]链式二叉树相关题目(c语言实现)

文章目录 LeetCode965. 单值二叉树LeetCode100. 相同的树LeetCode101. 对称二叉树LeetCode144. 二叉树的前序遍历LeetCode94. 二叉树的中序遍历LeetCode145. 二叉树的后序遍历LeetCode572. 另一棵树的子树 LeetCode965. 单值二叉树 题目 Oj链接 思路 一棵树的所有值都是一个…

mysql面试题33:Blob和text有什么区别

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:Blob和text有什么区别 Blob和text是数据库中存储大文本数据的两种数据类型&#…

都2023年了,你必须知道的几款主流性能测试工具!

市面上流行的压力/负载/性能测试工具多是来自国外,近年来国内的性能测试工具也如雨后春笋崛起。同时由于开发的目的和侧重点不同,其功能也有很大差异,下面就为您简单介绍10款目前最常见的测试产品。 1、kylinTOP测试与监控平台(商…

Transformer为什么如此有效 | 通用建模能力,并行

目录 1 更强更通用的建模能力 2 并行计算 3 大规模训练数据 4 多训练技巧的集成 Transformer是一种基于自注意力机制的网络,在最近一两年年可谓是大放异彩,我23年入坑CV的时候,我看到的CV工作似乎还没有一个不用到Transformer里的一些组…

毕业设计项目选题Java高考志愿咨询平台 高考志愿填报助手系统源码+调试+开题+lw

💕💕作者:计算机源码社 💕💕个人简介:本人七年开发经验,擅长Java、Python、PHP、.NET、微信小程序、爬虫、大数据等,大家有这一块的问题可以一起交流! 💕&…

Netty 介绍

1 Netty 原理 Netty 是一个高性能、异步事件驱动的 NIO 框架,基于 JAVA NIO 提供的 API 实现。它提供了对TCP、UDP 和文件传输的支持,作为一个异步 NIO 框架,Netty 的所有 IO 操作都是异步非阻塞的,通过 Future-Listener 机制&…

jQuery 模版

一、安装 <script type"text/javascript" src"http://ajax.microsoft.com/ajax/jquery /jquery-1.4.min.js"></script> 二、元素隐藏/显示 &#xff0c;jQuery toggle() 通过 jQuery&#xff0c;可以使用 toggle() 方法来切换 hide() 和 sh…

关于系统/网络运维面试经验总结

一. 熟悉Linux命令 1. 最最最常问到的是 如何查看系统内存占用情况&#xff1f; ① free命令&#xff1a;free [-h][-m] 显示系统的内存使用情况&#xff0c;包括总内存、已使用内存、空闲内存等信息。其中&#xff0c;-m选项是以MB为单位来展示内存使用信息&#xff1b;-h选…

一些常见的测度

见 知乎 https://zhuanlan.zhihu.com/p/615270645

Linux添加新硬盘并挂载(mount)到目录下

首先列出文件系统的整体磁盘空间使用情况&#xff0c;可以用来查看磁盘已被使用多少空间和还剩余多少空间。 df -h 然后列出块设备信息&#xff1a;以树形展示你的磁盘以及磁盘分区信息 lsblk 现在有一块 3T 的磁盘 vdb&#xff0c;我们现在将它进行 磁盘分区 fdisk /dev/vd…

jdk的bin目录下的工具

Java Development Kit (JDK) 的 bin 目录包含了许多与 Java 开发和运行相关的命令。 以下是 bin 目录下一些常见的命令&#xff0c;包括 jps&#xff1a; java - 启动 Java 应用程序的命令。javac - Java 编译器&#xff0c;用于将 Java 源代码编译成字节码文件。javap - Java …

基于springboot实现家具销售电商平台管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现家具销售电商平台管理系统演示 摘要 社会的发展和科学技术的进步&#xff0c;互联网技术越来越受欢迎。网络计算机的交易方式逐渐受到广大人民群众的喜爱&#xff0c;也逐渐进入了每个用户的使用。互联网具有便利性&#xff0c;速度快&#xff0c;效率高&am…

Bootstrap关于盒子(盒模型)边距的设置

关于Bootstrap的盒子(盒模型)边距&#xff0c;其实在之前的很多示例代码中用到了。在博文 Bootstrap的CSS类积累学习 也有收集到不少相关的类。 详细的介绍&#xff0c;请大家参看下面这张图。 示例代码如下&#xff1a; <!DOCTYPE html> <html> <head>&l…

sface人脸相似度检测

sface人脸相似度检测&#xff0c;基于OPENCV&#xff0c;人脸检测采用yunet&#xff0c;人脸识别采用sface&#xff0c;支持PYTHON/C开发&#xff0c;图片来自网络&#xff0c;侵权请联系本人立即删除 yunet人脸检测sface人脸识别&#xff0c;检测两张图片的人脸相似度

华为OD机试 - 数组组成的最小数字(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#…

UI自动化测试:Selenium+PO模式+Pytest+Allure整合

本人目前工作中未涉及到WebUI自动化测试&#xff0c;但为了提升自己的技术&#xff0c;多学习一点还是没有坏处的&#xff0c;废话不多说了&#xff0c;目前主流的webUI测试框架应该还是selenium&#xff0c;考虑到可维护性、拓展性、复用性等&#xff0c;我们采用PO模式去写我…

基于Springboot实现点餐平台网站管理系统项目【项目源码+论文说明】

基于Springboot实现点餐平台网站管理系统演示 摘要 随着现在网络的快速发展&#xff0c;网上管理系统也逐渐快速发展起来&#xff0c;网上管理模式很快融入到了许多商家的之中&#xff0c;随之就产生了“点餐平台网站”&#xff0c;这样就让点餐平台网站更加方便简单。 对于本…

设计模式 - 行为型模式考点篇:观察者模式(概述 | 案例实现 | 优缺点 | 使用场景)

目录 一、行为型模式 1.1、观察者模式 1.1.1、概述 1.1.2、案例实现 1.1.3、优缺点 1.1.4、使用场景 一、行为型模式 1.1、观察者模式 1.1.1、概述 观察者模式又称为 发布 - 订阅 模式.&#xff0c;就是让多个观察者对象同时监听同一个主题对象. 这个主题对象在变化的同…

详解一典型的反激式开关电源方案

理解一个单端反激式开关电源方案&#xff1a; 1、抛出问题&#xff1a; 如图&#xff0c;在某系统方案上看到下图所示的单端反激式开关电源方案。 2、解析问题&#xff1a; 2.1、乍一看&#xff1a; 典型的AC-DC电路&#xff0c;考虑了安规及过压过流保护&#xff0c;如&am…

黑马点评-06缓存雪崩问题(大量key失效)及其解决方案

缓存雪崩问题(大量key失效) 解决方案 缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库给服务器带来巨大压力 当我们批量导入缓存数据的时候可以给不同的Key的TTL添加随机值,让其在不同时间段分批失效利用Redis集群提高服务的可用性 使…