【JVM】Java虚拟机

news2024/11/26 16:48:14

本文主要介绍了JVM的内存区域划分,类加载机制以及垃圾回收机制.

其实JVM的初心,就是让java程序员不需要去了解JVM的细节,它把很多工作内部封装好了.但是学习JVM的内部原理有利于我们深入理解学习Java. 

1.JVM的内存区域划分

JVM其实是一个java进程 ; 每个java进程,就是一个jvm的实例

JVM的内存区域划分

放new的对象

方法区(元数据区)

放类对象,类(.class文件),方法内容,static成员

放方法的调用关系 , 局部变量

注意:

栈空间和程序计数器,是每个线程有一份.(每个线程都有一个独立的执行逻辑)

面试题:给一段代码,问某个变量在哪个内存区域中

2.JVM类加载机制

类加载:Java程序最开始写的是一个.java文件,编程成.class文件.运行java程序的时候,JVM会读取.class文件,把文件的内容放到内存中,并且构造成.class对象(类对象)   . 也就是把类从硬盘文件中,加载到内存中.

类加载的大致过程

1.加载

找到.class文件,打开文件,读取文件内容,并且尝试解析格式

2.验证

检查当前的.class文件的格式是否符合要求.

3.准备

给类对象分配内存

最终的目的是构造出完成的类对象,分配存在+初始化

4.解析

主要是初始化类对象中涉及到的一些字符串常量

字符串常量在.class文件本身就已经存在,直接读到内存中.

此处是将字符串的符合引用(偏移位置)替换为直接引用/真实的内存地址的过程

5.初始化

对类对象进行更具体地初始化操作,初始化静态成员,执行静态代码块,加载父类.

双亲委派模型

描述了类加载过程中,如何找.class文件

JVM中加载.class文件,需要用到类加载器模块 . JVM中自带了三个类加载器 .

Bootstrap ClassLoader

负责加载标准库的类. Java有一个标准文档,描述了都要提供的类

Extension ClassLoader

负责加载JVM扩展的库.   除了标准库之外,实现JVM的厂商,还会再添加一些类

Application ClassLoader

负责加载第三方库.  比如mysql jdbc driver / servlet / jackson

关系

第一个是第二个的父亲

第二个是第三个的父亲

此处的父子不是子类继承父类.而是对象里有一个parent引用指向父类加载器实例.

流程:

1.从Application ClassLoader开始

不会立即搜索第三方库的目录,而是先把加载任务委派给父亲,让父亲尝试加载

2.到了Extension ClassLoader

也不会立即就搜索到扩展库的目录,也是把加载任务委派给父亲.也让父亲先尝试加载

3.到了Bootstrap ClassLoader

也不会立即标准库,而是也想把任务委派给父亲,但是bootstrap ClassLoader没有父亲,就只能自己动手搜索类了.

目的:明确优先级.

标准库的类最优先加载 - >扩展库其次 -> 第三方库最低.

比如:

标准库中有一个java.lang.String , 自己写的代码中也有一个java.lang.String

JVM始终都是先加载标准库,而不会加载自己写的类, 避免程序员的代码,对标准库的代码产生负面影响.


一个类,什么时候会被加载

懒汉模式  ---- 用到才加载.

1.构造类的实例

2.使用了类的静态方法/静态属性

3.子类的加载会触发父类

类加载之后,后续使用就不必加载了.


类卸载

把对象干掉

一般情况下,不会考虑卸载,一直会保持到程序运行结束

热补丁(重启服务器)

有时候代码有bug,正常操作是修改代码,重新编译,新版本替带旧版本,重启服务器

冷不丁(不用重启服务器)

有些情况,不方便重启,就可以打补丁,通过一些方法把旧版本的类给卸载掉,直接用加载好的新的类替换,不重启服务器,也可以更新代码 .

3.垃圾回收 GC

C语言通过malloc申请的内存需要程序员手动释放,这当然是非常不靠谱的做法.而Java引入垃圾回收机制,可以自动的判定某个内存是否会继续使用;如果不会,就会把这个内存当成垃圾,自己把垃圾释放掉.再Java的影响下,后续的python/Go/PHP/Ruby大部分语言都采取了垃圾回收方式来释放内存.

而c++由于希望和C兼容还有对性能的追求,并没有引入垃圾回收机制.

引入GC机制就会引入额外的系统开销,并且还会可能影响程序效率.

可幸的是,Java中的GC已经优化多年,对于效率的影响已经越来越小了.


回收什么?

对于Java 来说,垃圾回收,回收的其实是对象,而不是字节

JVM中有好几个内存区域,GC回收的是哪里的对象

  • 占空间不需要GC对象,栈里面包含很多栈帧,每个栈帧对应一个方法,该方法执行结束,此时这个栈帧就销毁了,栈帧上的局部变量自然销毁
  • 每个栈帧都有的程序计数器/线程销毁,自然也销毁.
  • 方法区:类对象很少会涉及到对象的卸载
  • 堆:GC的主战场.

步骤

垃圾回收分两步:

1.判定对象是否是垃圾

垃圾:如果一个对象在后续代码中,不会被继续使用到了; Java中如果没有任何引用指向它,那它就是垃圾了 .

(在Java中,使用一个对象的唯一途径是:声明一个引用指向它,然后再通过引用访问对象)

引用计数

思路1:引用计数(Python/PHP的虚拟机的GC使用的是该方法)

给对象内部安排一个计数器,每次有引用指向它,计数器+1;每次引用被销毁,计数器-1 ;

当计数器为0,意味着对象就是垃圾.

这种方案的缺陷:

1.空间利用率低,浪费更多的内存空间

每个对象都要一块空间来存储引用计数.

2.可能存在循环引用的问题. 导致对象不能被正确地识别.

可达性分析

思路2(Java使用)

JVM首先会从现有代码中的能直接访问到的引用(栈上的局部变量/常量池里的引用/方法区里的静态成员)出发,尝试遍历所有能访问到的对象.

只要对象能访问到,就会标记成"可达",完成整个遍历之后,可达之外的对象,也就是"不可达",

也就相当于是垃圾了.

gc roots进行这样的扫描 :

这个遍历的过程就是可达性分析.

和引用计数不同,引用计数消耗的是空间;而可达性分析,消耗的是时间,并不会引入额外的空间开销,但是进行上述的遍历,需要消耗时间.

 由于一个对象是否是垃圾,往往是动态变化的.因此可达性分析是周期性的

2.释放对象

如何清理垃圾/释放对象

1.标记清楚 (直接释放)

直接释放对象,就会引起内存碎片

由于申请内存的时候,都是连续的的内存空间;如果释放,就可能会破坏原有的连续性,导致有内存,但是申请不了.

内存碎片随着程序的运行越来越多,越来越碎,内存就更难申请了.

2.复制算法

复制算法,通过冗余的内存空间,把有效对象复制到另一部分空间,来避免内存碎片

把一个内存分成两份,用一份,丢一份;

把左侧区域中有效的对象复制到右侧,接下来就可以使用右侧区域;

等右侧产生的很多碎片,再将对象复制到左侧,右边空间统一释放 ; 来回利用

缺陷:如果复制的内容很多,开销大;空间利用率也不高.

3.标记整理

类似于顺序表删除元素,搬运元素

缺陷:搬运成本高.

上述三种方法都有各自的缺陷

JVM采取的方法是在不同的场景下,使用不同的回收方式.

对象可以分为两类,一类是生命周期比较长的,一类是生命周期比较短的 ; 生命短的经历gc扫描的次数就少 ,生命长的经历gc扫描的次数就多 .  我们就可以将这两种对象放在不同的区域内,根据他们的特点使用不用的方法解决内存碎片问题 .

  • 新生代 : 每一轮gc留下的对象比较少, 复制开销不大, 以复制算法为主
  • 老年代 : 出现回收的概率比较低,此时搬运的开销不大. 以标记整理为主
  • 特殊情况: 如果对象体积特别大,就会直接进入老年带(大对象不适合进行复制算法)

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

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

相关文章

茶百道:门店数量狂飙,食品安全问题成最大绊脚石

茶百道近日传出即将在香港进行非交易路演,计划在今年内登陆港交所上市,消息一出引发市场广泛关注。然而,茶百道的上市能否成为其自救的解药,还存在诸多质疑。 茶百道的惊人营收增长背后,门店数量的迅速扩张功不可没。在…

Windows10安装麒麟桌面V10双系统

概述 想要在Windows10操作系统中安装麒麟V10的桌面操作系统(Kylin-Desktop-V10-Professional-Release-Build1-210203-X86_64) 安装前准备 1、先搞清楚自己的电脑类型 A MBR传统bios单硬盘 B MBR 传统bios双硬盘(SSD固态硬盘机械硬盘&…

PatchMatchNet笔记

PatchMatchNet笔记 1 概述2 PatchmatchNet网络结构图2.1 多尺度特征提取2.2 基于学习的补丁匹配 3 性能评价 PatchmatchNet: Learned Multi-View Patchmatch Stereo:基于学习的多视角补丁匹配立体算法 1 概述 特点   高速,低内存,可以处理…

SQLMAP --TAMPER的编写

跟着师傅的文章进行学习 sqlmap之tamper脚本编写_sqlmap tamper编写-CSDN博客 这里学习一下tamper的编写 这里的tamper 其实就是多个绕过waf的插件 通过编写tamper 我们可以学会 在不同过滤下 执行sql注入 我们首先了解一下 tamper的结构 这里我们首先看一个最简单的例子…

python基于DETR(DEtection TRansformer)开发构建人员手持物品检测识别分析系统

PyTorch训练代码和DETR(DEDetection-TRansformer)的预训练模型。我们用Transformer替换了完全复杂的手工制作的对象检测管道,并将Faster R-CNN与ResNet-50匹配,使用一半的计算能力(FLOP)和相同数量的参数在…

React升级到18版本

前言 升级前react版本是16.9.0,react-dom版本为16.9.0,react-router-dom为5.1.2版本。 安装 // npm npm install react react-dom// yarn yarn add react react-dom// pnpm pnpm install react react-dom启动项目 此时,项目可以正常运行&…

【python】——控制语句和组合数据类型(其二)

🎃个人专栏: 🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客 🐳Java基础:Java基础_IT闫的博客-CSDN博客 🐋c语言:c语言_IT闫的博客-CSDN博客 🐟MySQL&#xff1a…

【开源】基于JAVA的服装店库存管理系统

项目编号: S 052 ,文末获取源码。 \color{red}{项目编号:S052,文末获取源码。} 项目编号:S052,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 角色管理模块2.3 服…

OpenCV技术应用(3)— 把.png图像保存为.jpg图像

前言:Hello大家好,我是小哥谈。本节课就手把手教你如何把.png图像保存为.jpg图像,希望大家学习之后能够有所收获~!🌈 目录 🚀1.技术介绍 🚀2.实现代码 🚀1.技术介绍 如果在电脑某…

image is being used by stopped container 7d2ff8620f3b 删除镜像失败怎么办

这个错误信息表明,镜像 55860ee0cd73 正被一个已停止的容器 7d2ff8620f3b 使用,因此无法正常删除。要解决这个问题,你有两个选择: 删除使用该镜像的容器:首先删除引用该镜像的容器,然后再删除镜像。这可以通…

到站上海!见证这座零碳园区的绿色低碳新选择

不知不觉中,科士达新能源的零碳足迹已遍布五洲四海,为全球各地,千行百业、千家万户,带去了源源不断的绿色能源和低碳新选择。再次启航,这一站,抵达上海世博园。 小机身,大配置,灵活适…

扬帆未来,成就架构之路:十本书籍助力你的架构师梦想 | 文末送书

相信大家都对未来的职业发展有着憧憬和规划,要做架构师、要做技术总监、要做CTO。对于如何实现自己的职业规划也都信心满满,努力工作、好好学习、不断提升自己。 规划职业发展 当涉及未来职业发展时,我们都怀揣着远大的目标和野心。对许多人…

移动硬盘打不开?正确操作方法分享!

“我的移动硬盘用了好几年了,但是不知道为什么,最近每次把移动硬盘插入电脑都显示无法打开。我还有一些很重要的数据在里面呢,有什么比较好的方法可以解决这个问题吗?” 作为一个便捷的存储工具,移动硬盘给我们带来了很…

【汇编】内存中字的存储、用DS和[address]实现字的传送、DS与数据段

文章目录 前言一、内存中字的存储1.1 8086cpu字的概念1.2 16位的字存储在一个16位的寄存器中,如何存储?1.3 字单元 二、用DS和[address]实现字的传送2.1 字的传送是什么意思?2.2 要求原理解决方案:DS和[address]配合8086传送16字节…

【LeetCode刷题-滑动窗口】--340.至多包含K个不同字符的最长子串

340.至多包含K个不同字符的最长子串 class Solution {public int lengthOfLongestSubstringKDistinct(String s, int k) {int len s.length();if(len < k){return len;}//滑动窗口的左右指针int left 0,right 0;//定义一个哈希映射HashMap<Character,Integer> hash…

外汇天眼:世界级的交流碰撞!Wiki Finance EXPO悉尼2023圆满落幕

11月16日对于外汇天眼来说是个特殊的日子&#xff0c;而对于整个世界金融界来说也是一个意义非凡的日子&#xff0c;由WikiGloba展会品牌WiKiEXPO举办的2023 Wiki Finance Expo在悉尼富丽敦酒店顺利举办并圆满落幕。 金融科技作为金融业创新变革的重要引擎&#xff0c;在全球数…

【Python基础篇】字符串的拼接

博主&#xff1a;&#x1f44d;不许代码码上红 欢迎&#xff1a;&#x1f40b;点赞、收藏、关注、评论。 格言&#xff1a; 大鹏一日同风起&#xff0c;扶摇直上九万里。 文章目录 一 Python中的字符串拼接二 join函数拼接三 os.path.join函数拼接四 号拼接五 &#xff0c;号…

【开源】基于JAVA的高校宿舍调配管理系统

项目编号&#xff1a; S 051 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S051&#xff0c;文末获取源码。} 项目编号&#xff1a;S051&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能需求2.1 学生端2.2 宿管2.3 老师端 三、系统…

⑩② 【MySQL索引】详解MySQL`索引`:结构、分类、性能分析、设计及使用规则。

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ MySQL索引 ⑩② 【MySQL索引】1. 索引2. 索引的…

Spring Cloud Netflix微服务组件-Hystrix

目录 Hystrix的主要功能 传统容错手段 超时机制 应用容错三板斧 超时机制 舱壁隔离 熔断降级 侵入式Command用法 改进版一&#xff1a;ribbon与hystrix组合 改进版二&#xff1a;feign与hystrix组合 Hystrix三态转换图 源码分析 流程图 原理流程图 核心实现流程…