【JVM】(内存区域划分 为什么要划分 具体如何分 类加载机制 类加载基本流程 双亲委派模型 类加载器 垃圾回收机制(GC))

文章目录

  • 内存区域划分
    • 为什么要划分
    • 具体如何分
  • 类加载机制
    • 类加载基本流程
    • 双亲委派模型
      • 类加载器
  • 垃圾回收机制(GC)


内存区域划分

为什么要划分

JVM启动的时候会申请到一整个很大的内存区域,JVM是一个应用程序,要从操作系统这里申请内存,JVM就需要根据,把空间,分成几个部分,每个部分各自有不同的功能作用.

具体如何分

在这里插入图片描述

存放new出来的对象
方法区/元数据区,存放类对象(类加载之后,存放的位置)
存放方法之间的调用关系
程序计数器 存放每个线程,下一条要执行的指令的地址

在这里插入图片描述

类加载机制

类加载基本流程

java代码会被编译成.class文件(包含一些字节码),java程序要想运行起来,就需要让jvm读取到这些.class文件,并且把里面的内容,构造成类对象,保存到内存的方法区中。所谓的执行代码就是调用方法。
书上和官方文档把类加载过程分成了5个步骤。

  1. 加载:找到.class文件,打开文件,读取到文件内容。
  2. 验证:.class文件是一个二进制的格式。(某个字节,都是具有特定含义的),就需要验证你当前读到的这个格式是否符合要求。
  3. 准备:给类对象分配内存空间。(只分配内存空间,没有初始化,此时空间上的内存的数值是0,此时如果尝试打印类的static成员,就是全0的)
  4. 解析:针对类对象中包含的字符串常量进行处理,进行一些初始化操作。(java代码中用到的字符串常量在编译之后也会进入到.class文件中)这个过程也叫做:把“符号引用”(文件偏移量)替换成“直接引用”(内存地址)。
  5. 初始化:针对类对象进行初始化,把类对象中需要的各个属性都设置好,还需要初始化好static成员,还需要执行静态代码块,还可能需要加载一下父类。

双亲委派模型

属于类加载中,第一个步骤“加载”过程中国,其中的一个环节。
负责根据全限定类名找到.class文件。

所谓的“双亲委派模型”就是一个查找优先级问题。

类加载器

是JVM中的一个模块,在JVM中内置了三个类加载器。

  1. BootStrap ClassLoader
  2. Extension ClassLoader
  3. Application ClassLoader

上述三个类加载有父子关系,3是子 2是父 3是爷。
在这里插入图片描述

双亲委派模型过程:

类加载的过程(找class文件的过程)

  • 给定一个类的全限定类名,形如java.lang.String。
  • 从Application ClassLoader作为入口,开始执行查找的逻辑。
  • Application ClassLoader,不会立即去扫描自己负责的目录(负责的是搜索项目点前目录和第三方库对应的目录)而是把查找的任务,交给他的父亲,Extension ClassLoader。
  • Extension ClassLoader 也不会立即去扫描自己负责的目录,(负责的是JDK中一些扩展的库,对应的目录)而是把查找的任务,交给他的父亲,BootStrap ClassLoader。
  • BootStrap ClassLoader 也不想立即扫描自己负责的目录,(负责的是标准库的目录),也想把任务交给它的父亲,结果发现自己没有父亲,因此BootStrap ClassLoader只能亲自负责扫描,标准库的目录。java.lang.String这种类就能够在标准库中,找到对应的.class文件,就可以进行打开文件,读取文件后续操作。此时查找.class文件的过程就结束了。但是,如果给定的类不是标准库的类,任务仍然会被交给孩子来执行。
  • 如果没有扫描到就会回到Extension ClassLoader。Extension ClassLoader就会扫描负责的扩展库的目录,如果找到,就执行后续的类加载操作,此时查找过程结束,如果没找到,还是把任务交给孩子来执行。
  • 没有扫描到,就会回到Application ClassLoader,Application ClassLoader就会负责扫描当前目录和第三方库的目录,如果找到,就会执行后续的类加载操作,如果没找到,就会抛出一个ClassNotFoundExcepton。

之所以搞这一套流程,主要目的是为了确保,标准库的类,被加载的优先级最高,其次是扩展库,最后是自己写的类和第三方库

在这里插入图片描述

在这里插入图片描述

垃圾回收机制(GC)

让JVM自行判定,某个内存是否就不再使用了,如果这个内存后面确实不用了,JVM就会自动的把这个内存给回收掉,此时就不必要让程序员自己手动写代码回收。

GC这么好为什么C++不引入GC呢?

  1. 系统缺陷,需要一个/一些特定的线程,不停的扫描内存中的所有的对象,看是否能够回收。此时是需要额外的内存 + CPU资源的。C++要考虑能兼容一些配置特别低的系统。
  2. 效率问题,这样的扫描线程,不一定能够及时的释放内存(扫描总是有一定周期的),一旦同一时刻,出现大量的对象都需要被回收GC产生的负担就会很大,甚至引起整个程序都卡顿。(STW问题 stop the world)。
    GC是垃圾回收,GC回收的目标是内存中的对象,对于Java来说就是new出来的对象。栈里的局部变量,是跟随栈帧的生命周期走的。(方法执行结束,栈帧销毁,内存自然释放)
    静态变量,生命周期就是整个程序,这个始终存在,就意味着静态变量是无需释放的。

GC可以理解成两个大的步骤:

  • 找到垃圾
  1. 引用计数(Python PHP)
    new出来的对象,单独安排一块空间,来保存一个计数器。
    在这里插入图片描述
    缺陷:
    1.浪费内存
    在这里插入图片描述
    2.引用计数机制,存在“循环引用”问题。

在这里插入图片描述
此时第一个对象和第二对象互相引用,要想使用第一个对象,就需要先拿到第二个对象,如果想要拿到第二个对象,又得先拿到第一个对象,这里就非常像死锁。

  1. 可达性分析(Java)

本质上就是时间换空间这样的手段,有一个/一组线程,周期性的扫描我们代码中所有的对象。(从一些特定的对象触发,尽可能的进行访问的遍历,把所有能够访问到的对象都标记成“可达”,反之经过扫描之后,未被标记的对象就是垃圾(“不可达”)了)
可达性分析出发点很多,不仅仅是所有的局部变量,还有常量池中引用的对象,还有方法区中的静态引用的变量。 这些统称为GCRoots。
可达性分析都是周期性进行的,当前某个对象是否是垃圾,是随着代码的执行,会发生改变。(可达性分析比较消耗系统资源,开销比较大)

  • 回收垃圾

三种基本思路

  1. 标记清除

把对应的对象,直接释放掉,就是标记清楚的方案,这个方案会产生很多的内存碎片,释放内存是为了让别的代码能够申请,申请内存,都是申请到“连续”的内存空间。

优点:实现简单。

缺点:产生不连续的内存碎片,如果程序需要分配一个连续内存的大对象时,就需要提前触发一次垃圾回收。

在这里插入图片描述

  1. 复制算法

通过复制的方式把有效的对象,归类到一起,再统一释放剩下的空间。

在这里插入图片描述
优点:执行效率高,没有内存碎片的问题。

缺点:空间利用率低,因为复制算法每次只能使用一半的内存。

  1. 标记整理

既能够解决内存碎片化的问题,又能够处理复制算法中利用率低的问题。

类似于顺序表删除元素的搬运操作。搬运的开销仍然很大。
在这里插入图片描述
优点:解决了内存碎片问题,比复制算法空间利用率高。

缺点:因为有局部对象移动,所以效率不是很高。

实际上JVM采取的释放思路,是上述基础思路结结合体,让上述方案扬长避短。

分代回收:

在这里插入图片描述

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

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

相关文章

【Leetcode-73.矩阵置零】

题目: 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1: 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]]示例 2&…

如何写好Stable Diffusion的prompt

Stable Diffusion是一种强大的文本到图像生成模型,其效果在很大程度上取决于输入的提示词(Prompt)。以下是一些关于如何编写有效的Stable Diffusion Prompt的秘诀: 明确描述:尽量清晰地描述你想要的图像内容。使用具体…

2024全新返佣商城分销商城理财商城系统源码 全开源PHP+VUE源码

2023全新返佣商城分销商城理财商城系统源码 全开源PHPVUE源码 程序安装环境要求: nginx1.16 php7.2 mysql5.6 程序全开源PHPVUE源码 有需要测试的老铁,拿去测试吧

Linux_基础指令(一)

目录 1、ls指令 1.1 ls -l 1.2 ls -a 1.3 ls -i 2、pwd指令 3、cd指令 3.1 路径的概念 3.1.1 绝对路径 3.1.2 相对路径 3.2 cd ~ 3.3 cd - 4、touch指令 5、mkdir指令 6、删除系列的指指令 6.1 rmdir 6.2 rm 7、man指令 8、cp指令 9、move指令 结…

【Java】十大排序

目录 冒泡排序 选择排序 插入排序 希尔排序 归并排序 快速排序 堆排序 计数排序 桶排序 基数排序 冒泡排序 冒泡排序(Bubble Sort)是一种简单的排序算法。它重复地遍历要排序的序列,依次比较两个元素,如果它们的顺序错误就把它们交换过来。遍历…

论文阅读_参数微调_P-tuning_v2

1 P-Tuning PLAINTEXT 1 2 3 4 5 6 7英文名称: GPT Understands, Too 中文名称: GPT也懂 链接: https://arxiv.org/abs/2103.10385 作者: Xiao Liu, Yanan Zheng, Zhengxiao Du, Ming Ding, Yujie Qian, Zhilin Yang, Jie Tang 机构: 清华大学, 麻省理工学院 日期: 2021-03-18…

东京旅行攻略:机票、交通、消费和看富士山

欢迎关注「苏南下」 在这里分享我的旅行和影像创作心得 分享一些最近从香港去日本东京的短期周末旅行体验。 1:香港飞东京需要4小时,非旺季往返的价格在2000元左右。去年五一假期,我提前了两个多月买的香港快运就是这个价,不算贵。…

微信小程序的页面制作---常用组件及其属性

微信小程序里的组件就是html里的标签,但其组件都自带UI风格和特定的功能效果 一、常用组件 view(视图容器)、text(文本)、button(按钮)、image(图片)、form&#xff08…

Sentinel篇:线程隔离和熔断降级

书接上回:微服务:Sentinel篇 3. 隔离和降级 限流是一种预防措施,虽然限流可以尽量避免因高并发而引起的服务故障,但服务还会因为其它原因而故障。 而要将这些故障控制在一定范围,避免雪崩,就要靠线程隔离…

【Visual Studio】VS转换文件为UTF8格式

使用高级保存选项 更改VS的编码方案 首先需要打开高级保存选项 然后打开 文件 —> 高级保存选项 即可进行设置

OSPF协议全面学习笔记

作者:BSXY_19计科_陈永跃 BSXY_信息学院 注:未经允许禁止转发任何内容 OSPF协议全面学习笔记 1、OSPF基础2、DR与BDR3、OSPF多区域4、虚链路Vlink5、OSPF报文6、LSA结构1、一类/二类LSA(Router-LSA/Network-LSA) 更新完善中... 1、…

ChatGPT :确定性AI源自于确定性数据

ChatGPT 幻觉 大模型实际应用落地过程中,会遇到幻觉(Hallucination)问题。对于语言模型而言,当生成的文本语法正确流畅,但不遵循原文(Faithfulness),或不符合事实(Factua…

C++——string

一学习string的原因 1.从个人理解角度上: 在刚开始学习之前,我只知道学习完string在以后的刷题中能提高做题效率,在对字符串的处理string库中也许有对应的接口去实现需求,不用自己去写函数的实现。 但在学string中改变了之前的…

【PyTorch】基础学习:一文详细介绍 torch.save() 的用法和应用

【PyTorch】基础学习:一文详细介绍 torch.save() 的用法和应用 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f44…

Flask中的Blueprints:模块化和组织大型Web应用【第142篇—Web应用】

👽发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 Flask中的Blueprints:模块化和组织大型Web应用 在构建大型Web应用时&#xff0…

最后的挣扎 - Qt For Android on HuaWei Mate 60Pro (v4.0.0)

简介 为什么叫最后的挣扎, 其实都知道即将到来的 HarmonyOS NEXT 将抛弃Android支持,纯血HarmonyOS 将上线, 此时再说Qt for android支持Huawei HarmonyOS的设备其实并没有多少意思, 但恐怕在大多数基础软件完成兼容前, 很多人还是…

【PyTorch】基础学习:一文详细介绍 torch.load() 的用法和应用

【PyTorch】基础学习:一文详细介绍 torch.load() 的用法和应用 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f44…

UCORE 清华大学os实验 lab0 环境配置

打卡 lab 0 : 环境配置 : 首先在ubt 上的环境,可以用虚拟机或者直接在windows 上面配置 然后需要很多工具 如 qemu gdb cmake git 就是中间犯了错误,误以为下载的安装包,一直解压不掉,结果用gpt 检查 结…

LeetCode 189.轮转数组

题目:给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 思路: 代码: class Solution {public void rotate(int[] nums, int k) {int n nums.length;k k % n;reverse(nums, 0, n);revers…

sqlite 常见命令 表结构

在 SQLite 中,将表结构保存为 SQL 具有一定的便捷性和重要性,原因如下 便捷性: 备份和恢复:将表结构保存为 SQL 可以方便地进行备份。如果需要还原或迁移数据库,只需执行保存的 SQL 脚本,就可以重新创建表…