复习之 JVM【类加载机制,内存模型,GC 】

news2024/11/25 23:02:42

裁员在家,没有面试机会,整理整理面试知识点吧!

JVM 全名 Java Virtual Machine(Java虚拟机)

Java中的所有类,必须被装载到JVM中才能运行,这个装载工作是由jvm中的类装载器完成的,.class文件可以在虚拟机运行,但不是直接和操作系统交互,需要jvm解释给操作系统,解释的时候需要java类库,这样就能和操作系统交互。

类加载器:启动类加载器,扩展类加载器,应用程序类加载器。自定义类加载器

类加载机制 :

加载:加载编译后的class 文件。

验证:验证class 文件是否符合java 虚拟机规范 比如(是否以CAFEBABE 开头,是否存在父类继承是否正确,final 不能被继承 等等吧。因为class 文件可能从网上拿过来,可能被修改)

准备:静态变量申请内存空间,赋初默认值。

解析:符号引用转换成直接引用。类里 User user = new User(); 此时user 就是符号引用。她只是一个符号user 没有任何意义,当解析的时候 会将user 符号替换成 new User() 在堆里指针,指向堆里的user 实例对象。。

初始化:  静态变量,初始化代码块执行初始化操作。

双亲委派机制:   

一个类过来首先要通过自定义类加载器加载,判断如果加载过则跳出,如果没有加载则通过父类加载,向上委派,递归加载直到找到启动类加载器。如果启动类加载加载不了,在向下委派,由子类加载器加载。

打破双亲委派机制:tomcat

一个tomcat 可以部署多个项目,加入项目1 用的时spring4 ,项目2 用的时spring5 。先加载项目1 ,再加载项目2的时候开始加载spring5 发现相同包下相同的类都已经被加载了,就不会再去加载了,但是实际上spring5 没有被加载,加载的时spring4 就会出现问题,所以tomcat 通过自定义类加载器的方式去打破双亲委派,每个项目自己加载自己的

Tomcat破坏双亲委派原则,提供隔离机制,为每个web容器单独提供一个WebAppClassLoader加载器。优先加载 Web 应用自己定义的类,没有遵照双亲委派的约定,
每一个应用有自己的类加载器——WebAppClassLoader负责加载本身的目录下的class文件,加载不到时再交给CommonClassLoader加载,这和双亲委派刚好相反。
  

JVM 内存模型

JVM 虚拟机主要分成5部分:

java 堆(线程共享):主要存储java对象的,堆分年轻代(1/3),老年代(2/3),年轻代又分Eden(8/10),S0(1/10),S1(1/10)。垃圾回收也主要是回收堆区的。如果频繁FGC 会导致系统卡顿,这时候需要进行排查了。整个垃圾回收的时候再说。(jdk1.8 字符串常量池也放到堆中)

方法区(线程共享):常量池,静态变量,方法信息(修饰符、方法名、返回值、参数等),类元信息

虚拟机栈(线程独有):主要存储局部变量,生命周期和线程同步,线程结束,栈内存就释放了。不存在垃圾回收问题。虚拟机栈储存的是:8大基本类型 + 对象引用 + 实例方法。线程栈又存在多个栈帧,一个请求过来可能调用多个方法,每个方法就是一个栈帧,每个栈帧存储自己的局部变量。

本地方法栈:本地接口库里调用的方法,就是java里面native关键字修饰的方法。

程序计数器:多线程的情况下,会交替获取CPU 时间片执行,当t1 线程执行一半,t2线程获取CPU时间片执行,当t1 再次执行的时候要知道上一次执行到哪里了。每个线程启动是都会创建一个程序计数器,保存的是正在执行的jvm指令,程序计数器总是指向下一条将被执行指令的地址。生命周期与线程的生命周期保持一致。

面试点:

1 java 内存模型那些区域会报错OutOfMemoryError(OOM)

堆,栈,方法区都会报OOM ,程序计数器保存jvm 指令是再栈中,没有单独空间所以不会报OOM。

此处主要考 栈为什么也会报OOM 

OOM 主要是jvm 虚拟机内存满了,没有可申请的空间了,所以会报OOM 。

JVM 内存主要就是,堆内存,方法区内存,栈内存(虽然栈内存很小,且执行完马上释放,但是多线程同时请求,申请不到栈所需要内存大小了,就会报OOM 。)

StackOverFlowError 只线程栈嵌套太深,或者死循环,栈里局部变量占用内存大小超过申请内存空间大小–Xss配置。会报StackOverFlowError。

2 内存泄漏,内存溢出区别

内存泄漏:是指程序在运行过程中分配的内存空间无法被正常释放,‌导致内存的使用量不断增加,‌最终可能耗尽可用的内存

内存溢出:则是指程序在申请内存时无法获得所需的内存空间,‌导致程序运行停止并抛出“内存溢出”的错误

内存泄漏会导致内存溢出。

3 常用jvm 参数

-Xmx:JVM最大内存

-Xms:启动初始内存

-Xmn:新生代大小

-Xss : 每个线程虚拟机栈及堆栈的大小 

-XX:+HeapDumpOnOutOfMemoryError 表示打开开关:VM 出现 OOM 时 Dump 当前内存堆转储快照 。可通过工具(VisualVM  ,MAT)进行分析找出那些对象多,进行优化

==========================华丽丽的分割线================================

JVM GC :主要分三部分

可回收的对象:

可达性分析:通过GCRoot 的对象作为起点,从这些节点向下搜索,找到的对象为非垃圾对象,其余的为垃圾对象。

GCRoot: 线程栈的本地变量、静态变量、本地方法栈的变量

java 引用类型:强引用,软引用,弱引用,虚引用

强引用:强引用的对象回收基于“可达性分析”算法,当对象不可达时才可能会被回收。就算jvm内存满了,会抛出OutOfMemoryErro,也不会回收强引用

软引用:软引用是说一些有用但是非必需的对象。在jvm内存即将满的时候,会将软引用关联的对象,进行回收,如果回收之后,内存还是不够,才会抛出OutOfMemoryError。

弱引用:无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收。

虚引用:虚引用是最弱的一种引用关系,如果一个对象仅持有虚引用,那么它就和没有任何引用一样,随时可能会被回收

垃圾回收器:

serial 单线程 :年轻代 老年代,可做CMS 备选方案,垃圾回收时,应用线程停止

parNew 多线程 :年轻代 跟CMS 搭配使用

Parallel :内存大于2G cpu 大于2核 默认jvm 垃圾回收器 提高吞吐量 高效利用CPU 年轻代 复制算法,老年代 标记整理清除 可以设置 停顿时间,但是可能不能完全回收

CMS 减少卡顿时间 只能老年代(标记清除是对未标记的进行清除 老年代回收是默认到达百分之92 就回收,可以设置90 )

G1 大容量内存 用G1 满足吞吐量,及卡顿时间 年轻代老年代都可以G1

还有一些新出的垃圾回收器,暂时没有研究,后续再补充....

垃圾回收算法:

复制算法:主要用于年轻代。

标记清除算法:老年代,老年代都是存活比较长的,只要进入老年大大多数都是不会垃圾回收的,通过可达性分析,标记除不可回收的对象,其他的都是可以回收的对象

标记整理算法:标记清除算法,由于标记的对象中间可能存在很多内存需要回收,但是又不是连续的(内存碎片),导致导入如果出现大对象,老年代放不下。标记整理清除,就是标记后进行内存空间整理,再删除。

标记顺序:

初始标记:标记根节点。STW  用户线程不可用,但是标记时间短

并发标记:根据初始标记的根节点标记其引用的节点,此时非STW ,用户线程可用,标记时间长

重新标记:标记并发标记时产生的对象。STW 。时间短

并发清理:删除无用对象

YGC :当服务器接收请求,会产生对象,放到年轻代Eden 区,当Eden 区满了,会已经一次YGC 。把还存活的对象复制到s0区。第一次YGC 完成。当再有请求进来Eden满了,会去s0 申请空间,当s0也满了会进行第二次YGC,把Eden,S0 存活对象放到 S1 区里。

因为大多数java 对象程序执行完都会变成不可达对象,只有正在执行的线程引用的对象才是不可回收的对象,所以只有少部分存活对象。垃圾回收只需要把存活的对象复制到s 区即可,然后可以整体清除对象。

FGC: 多次YGC 没有回收掉的对象会转移到老年代。当老年代满了会触发FGC。

到达老年代的条件: 

当对象年龄超过15 没有被年轻代回收的。可以通过参数 -XX:MaxTenuringThreshold 来设置

大对象可直接进入老年代。jvm 可以配置多大对象  -XX:PretenureSizeThreshold=1m:大对象直接分配在老年代,这个参数只对 Serial 和ParNew两个收集器有效

动态年龄判断:当年轻代垃圾回收时,Survivor 一批对象大于该区域总大小的百分之50,年龄1 年龄2 年龄3 。。。年龄6 大于survivor 百分之50 则把 年龄6 包括年龄6 以后的对象会受到老年代,一般是在minor gc 之后。

老年代分配担保机制:在执行YGC之前,先回去看老年代剩余空间大小是否小于年轻代对象大小,如果是就先进行老年代回收,但是如果配置“-XX:-HandlePromotionFailure”(jdk1.8默认就设置了)的参数是否设置了。如果配置了 jvm 会再次检查一下 老年代剩余大小是否 小于以前年轻代回收的平均大小,如果小于,则进行老年代回收。

调优命令

jps  : 查看存活的进程 jps -l 查看全名

jinfo: 查看jvm 配置信息

jstat: 对java应用程序的资源和性能进行实时的命令行监控 。 jstat -gc 3776  查看进程的gc 信息

jstack 查看jvm 线程 它用于打印出给定的java进程ID、core file、远程调试服务的Java堆栈信息。

jmap 是 JDK 自带的一个命令行工具,可以用于生成 Java Heap Dump 文件,以及查看 Java 进程中的内存使用情况。jmap -histo 3776     jmap -heap 3776

jvm 调优主要就是减少进程的FGC ,频繁FGC 系统会容易卡顿。

CPU 标高,通过top 命令找到进程,找对应的线程 top -p pid -H,通过jstack 命令 查看堆栈日志根据线程id 找到对应的代码。

-XX:+HeapDumpOnOutOfMemoryError :内存溢出通过该参数打印错误日志。通过通过工具分析。

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

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

相关文章

如何一眼识破电子元器件缺陷?这台设备教你!

电子元器件外观缺陷检测设备是一种用于检测电子元器件外观缺陷的专业设备。随着电子元器件的广泛应用,对其质量和可靠性的要求也越来越高。而电子元器件外观缺陷是影响其性能和寿命的重要因素之一。因此,开发一种高效、准确的电子元器件外观缺陷检测设备…

Qt (6)【按钮类控件 | QPushButton | QCheckBox | QRadioButton | QToolButton】

阅读导航 引言一、按钮类控件概述(继承关系)二、QPushButton三、QRadioButton四、QCheckBox五、QToolButton 引言 在之前的文章中,我们聊到了Qt中QWidget的基础属性,它是构建所有GUI元素的基础。今天,我们要更进一步&…

低代码时代:重塑软件开发版图的机遇与挑战

低代码时代:重塑软件开发版图的机遇与挑战 在数字化转型的浪潮中,低代码(Low-Code)开发平台如同一股清新的风,迅速席卷了整个IT行业,以其“让非专业人士也能快速构建应用程序”的承诺,引发了广…

如何彻底清除硬盘数据不被恢复?保护隐私无忧

在数字时代,硬盘作为存储重要数据的主要设备,其安全性备受关注。当我们需要出售、赠送或报废电脑时,彻底清除硬盘上的数据以防止敏感信息泄露显得尤为重要。本文将详细介绍几种彻底清除硬盘数据且不可恢复的方法,帮助用户保护个人…

自制深度学习推理框架之计算图设计

文章目录 一、计算图1.1 计算图定义1.2 计算图的生成1.2.1 **静态计算图(Static Computational Graph)**1.2.2 **动态计算图(Dynamic Computational Graph)** 1.3 计算图功能1.3.1 训练阶段1.3.2 推理部署阶段 1.4 计算图的调度(执…

Datawhale X 魔搭 AI夏令营第四期-魔搭生图task3学习笔记

进入魔搭社区,找到我的Notebook选择对应运行环境 因为我是一天前登录的,所以需要重新使用相关账号重新登陆。大家可以根据自己的具体情况来登录,仅供参考 进入后,新建终端 在命令行输入如下命令下载安装ComfyUI的执行文件和task1中…

观察者模式(ObserverPattern)

文章目录 1.观察者模式定义2.UML类图3.实现代码 1.观察者模式定义 定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象 如果你订阅了一份杂志或报纸, 那就不需要再去报摊查询新出版的刊物了。 出版社 (即应用中的 “…

记录一个lombok和mybatisplus的问题,@Data注解失效

刚开始我这里一直爆红,Article实体类也加了Data注解 依赖也导入了lombok,后来觉得是版本的问题,换了几个版本也是不行 后来最后还是在各种资料下,找到了原因 首先使用lombok不是只要导入依赖就行的,还要有插件&#…

软件工程造价师习题练习 11

1.如果数据功能由被度量应用维护,则为一个EIF。 错误 正确 如果数据功能由被度量应用维护,则为一个ILF。如果数据功能由被度量应用引用但不维护,且其为其他应用的一个ILF,则为一个 EIF。 答案:错误 2.图书管理系统…

【傅里叶分析】复数基础知识

【傅里叶分析】复数基础知识 复数复数的几何意义与点的对应与向量的对应 复数与极坐标辐角与辐角主值三角函数 参考文献 本文参考了网上的其他文章,已在文末参考文献中列出;如有侵权,请联系我删除。 复变函数是傅里叶分析的基础,而…

OpenCV图像滤波(12)图像金字塔处理函数pyrDown()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 函数主要是对图像进行模糊处理并将其降采样。 默认情况下,输出图像的大小计算为 Size((src.cols1)/2, (src.rows1)/2),但…

初识C++(下):const引用/inline/nullptr

1.引用 1.1const引用 可以引用一个const对象&#xff0c;但是必须用const引用。const引用也可以引用普通对象&#xff0c;因为对象的访问权限在引用过程中可以缩小&#xff0c;但是不能被放大 #include<iostream>using namespace std;int main() {const int a 10;//权…

SpringBoot中整合RabbitMQ(测试+部署上线 最完整)

一、RabbitMQ安装 由于在测试环境中&#xff0c;我们现在虚拟机上基于docker安装mq docker run \-e RABBITMQ_DEFAULT_USERquick \-e RABBITMQ_DEFAULT_PASS123 \-v mq-plugins:/plugins \--name mq \--hostname mq \-p 15672:15672 \-p 5672:5672 \--network your-net\-d \r…

学习文本到语音转换技术时为何要掌握Mel频谱图?

理解Mel频谱图 “Mel”指的是梅尔频率刻度&#xff08;Mel Frequency Scale&#xff09;&#xff0c;这是一种基于人类听觉感知方式的频率刻度。梅尔频率刻度旨在更好地模拟人耳对声音的感知&#xff0c;因为人类对频率的感知并不是线性的&#xff0c;而是对低频更敏感&#x…

gitlab查看root密码

gitlab查看root密码 gitlab安装后会创建默认的root密码&#xff0c;密码存在配置文件cat /etc/gitlab/initial_root_password中。

深度解析Edge SCDN与CDN:安全加速,全面防护

在现代互联网应用中&#xff0c;CDN已成为提高网站和应用性能不可或缺的技术之一。然而&#xff0c;随着网络安全威胁的日益严峻&#xff0c;单纯依靠CDN提供的加速服务已经不足以满足企业的安全需求。因此&#xff0c;Edge SCDN出现了&#xff0c;它不仅具备CDN的加速特性&…

Selenium + Python 自动化测试12(unittest组织更多用例)

我们的目标是&#xff1a;按照这一套资料学习下来&#xff0c;大家可以独立完成自动化测试的任务。 上一篇我们讨论了unittest中test suite 的构建&#xff0c;可以测试多条测试用例。 本篇文章我们接着讲。使用discover()方法构建更多的测试用例。 1、引入需要完成的任务 上…

【鸿蒙教程】快速集成鸿蒙 IM SDK 并实现单聊发送消息

本文手把手教您快速集成鸿蒙版环信即时通讯 IM 并实现单聊。 教程目录 前提条件准备开发环境SDK导入及声明SDK 初始化注册监听回调注册登录发送消息 前提条件 DevEco Studio NEXT Developer Beta1&#xff08;5.0.3.300&#xff09;及以上&#xff1b;HarmonyOS SDK API 12…

4款视频剪辑免费软件推荐,剪辑必备的神器!

对于许多新入门的剪辑小白或者经费有限的剪辑朋友来说&#xff0c;寻找一款免费且好用的剪辑软件是非常重要的。今天&#xff0c;我就来给大家分享4款很实用且专业的免费剪辑软件。 1、福昕免费剪辑 直达链接&#xff1a;www.pdf365.cn/foxit-clip/ 第一个是款功能全面且易上…