【JVM】Java虚拟机

本文主要介绍了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留下的对象比较少, 复制开销不大, 以复制算法为主
  • 老年代 : 出现回收的概率比较低,此时搬运的开销不大. 以标记整理为主
  • 特殊情况: 如果对象体积特别大,就会直接进入老年带(大对象不适合进行复制算法)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

芸鹰蓬飞:抖店服务分怎么快速升分?

在这个平台上,抖店服务分数的高低直接关系到商家在抖音平台上的曝光和信任度。那么,如何快速提升抖店服务分,成为了广大商家亟需解决的问题。本文将从多个角度,深入探讨提升抖店服务分的有效方法。 一、了解抖店服务分的评估标准 …

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

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

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

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

Wordpress多语言插件:WPML插件使用教程,最佳的多语言建站方案

今天小编讲的是另外一款多语言插件WPML。相比Gtranslate采用的是机器翻译,难免存在翻译不准确,词不达意的情况,WPML可以支持人工翻译内容添加。 事先说明一点:用插件实现多语言较为方便,但此方法做出的多语言网站SEO性能一般,只建议展示站使用,如果想要SEO营销型多语言网…

猫罐头哪个牌子好?盘点十大猫罐头品牌排行榜!

作为一个多猫家庭的铲屎官,我之前一直购买性价比较高的德国进口猫罐头。然而,近来进口主食罐的频繁涨价让我不得不开始关注国产主食罐。在这篇文章中,我想与大家分享一些口碑较好的国产猫罐头品牌,希望能对你的选购决策提供一些参…

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

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

素质教育正式提出30周年 提高实际应用能力成为教育新选择

至2023年“素质教育”已正式提出30周年。在实施期间,素质教育取得了显著成就:不仅提高了学生的综合素质和竞争力,培养了学生的创新能力、实践能力等,同时也改变了应试导向和知识灌输的教育模式,建立了以人为本、以学为主的教育理念。 教育观念发生扭转,教育目标也随之改变。学…

猫罐头哪个牌子好?分享十款猫罐头品牌排行榜!

选择适合的猫罐头非常重要,好的猫罐头应该提供丰富的营养、适量的水分、口感良好,并且易于消化吸收。然而,如果选择不当,可能无法达到期望的效果,甚至可能对猫咪产生负面影响。 作为一位经营猫咖5年的老板,…

非 dict 字典类型的处理

在Python的requests库中,使用data参数发送POST请求时,如果传入的数据对象不是直接继承自dict的字典类型,就会抛出TypeError异常。 Python的requests库是一个广泛用于HTTP请求的库,它提供了丰富的功能来发送和处理HTTP请求。其中&…

原论文一比一复现 | 更换 RT-DETR 主干网络为 【VGG13】【VGG16】【VGG19】| 对比实验必备

本专栏内容均为博主独家全网首发,未经授权,任何形式的复制、转载、洗稿或传播行为均属违法侵权行为,一经发现将采取法律手段维护合法权益。我们对所有未经授权传播行为保留追究责任的权利。请尊重原创,支持创作者的努力,共同维护网络知识产权。 论文地址:https://arxiv.o…

BUG 随想录 - Java: 程序包 com.example.xxx 不存在

目录 一、BUG 复现 二、解决问题 一、BUG 复现 背景:通过 feign 的最佳实践,将 feign 单独提取成一个微服务,接着在需要远程调用的微服务中引入 feign 模块,并在启动类通过 EnableFeignClients 声明指定的 Feign 客户端. 出现问题…

搭建帮助中心系统!客户服务一站式解决方案

随着企业规模的扩大和客户需求的增加,提供高效、便捷的客户服务变得越来越重要。为了满足客户的需求,许多企业开始搭建帮助中心系统,为客户提供一站式的问题解决方案。接下来就跟大家介绍一下帮助中心系统,以及如何实现一流的客户…

图解分布式事务实现原理(三)

参考 本文参考https://zhuanlan.zhihu.com/p/650791238从零到一搭建 TCC 分布式事务框架,并在小徐的基础上增加个人见解笔记。 项目地址:https://github.com/xiaoxuxiansheng/gotcc 图解分布式事务实现原理(一):https…

云骑士数据恢复软件会对硬盘造成伤害吗?

当今时代,数据已经成为我们生活的重要组成部分,而硬盘又是存储数据的主要设备之一。然而,由于各种原因,我们的数据很容易丢失。是的,我们可以通过数据恢复软件来找回丢失的数据,但是这个过程是否会对硬盘造…

系列五、GC垃圾回收【四大垃圾算法-复制算法】

一、堆的内存组成 二、复制算法 2.1、发生位置 复制算法主要发生在新生代,发生在新生代的垃圾回收也被叫做Minor GC。 2.2、 Minor GC的过程 复制>清空》交换 1、eden、from区中的对象复制到to区,年龄1 首先,当eden区满的时候会触发第一…

微软Ignite 2023大盘点:GPT-4 Turbo、DALL-E 3等

11月16日,微软在美国西雅图举办“Microsoft Ignite 2023”全球开发者大会。ChatGPT等生成式AI成为了本次大会的重要主题。 下面「AIGC开放社区」将根据大会发布的内容,盘点重要内容。 GPT-4 Turbo、 DALL E 3等全新模型 16K上下文的新GPT-3.5 Turbo模…

五分钟,Docker安装kafka 3.5,kafka-map图形化管理工具

首先确保已经安装docker,如果是windows安装docker,可参考 wsl2安装docker 1、安装zk docker run -d --restartalways -e ALLOW_ANONYMOUS_LOGINyes --log-driver json-file --log-opt max-size100m --log-opt max-file2 --name zookeeper -p 2181:218…

操作指南|JumpServer堡垒机支持通过Passkey进行登录认证

伴随着互联网应用的深度普及,用户账户安全的重要性不言而喻。密码是目前互联网用户保护在线账户安全和隐私的主要手段。然而,传统密码技术本身也存在着一些缺陷。 首先,密码是由用户创建的,用户通常会出于易用性而非实际的安全性…

解决 uniapp 开发微信小程序 不能使用本地图片作为背景图 问题

参考博文:uniapp微信小程序无法使用本地静态资源图片(背景图在真机不显示)的解决方法_javascript技巧_脚本之家 问题:uniapp 开发微信小程序,当使用本地图片作为 background-image 时,真机无法显示 解决: 方法一&am…

Java智慧工地SaaS管理平台源码:AI/云计算/物联网

智慧工地是指运用信息化手段,围绕施工过程管理,建立互联协同、智能生产、科学管理的施工项目信息化生态圈,并将此数据在虚拟现实环境下与物联网采集到的工程信息进行数据挖掘分析,提供过程趋势预测及专家预案,实现工程…