JVM学习笔记总结

news2024/11/29 19:50:28

目录

JVM内存区域划分

 1、堆(线程共享)

2、方法区(线程共享)

3、栈(线程私有)

4、程序计数器(线程私有)

JVM类加载机制

加载

验证

准备

解析

初始化

双亲委派模型

JVM垃圾回收机制(GC)

1、寻找

引用计数法(Python、PHP采用)

可达性分析(Java采用)

2、释放

标记清除

复制算法

标记整理

分代回收


此篇学习笔记总结包括了3个方面的知识点:

1、JVM内存区域划分

2、JVM类加载机制

3、JVM垃圾回收机制

后面就将重点来介绍这3个方面的知识收获


JVM内存区域划分

JVM内存区域划分可以分为四部分:方法区(元数据区)程序计数器

 1、堆(线程共享)

堆的作用:程序中创建的所有对象都在保存在堆中,即new  出来的所有对象(全局变量、成员方法)

堆是JVM 中最大的内存区域

堆在JVM进程中,一个进程只有一个堆,进程内所有的线程共享一个堆

2、方法区(线程共享)

方法区的作用:用来存储被虚拟机加载的类信息、常量、静态变量、编译器编译后的代码等数据,即类加载之后的类对象(静态变量、静态方法)
方法区在JVM进程中,一个进程只有一个方法区,进程内所有的线程共享一个方法区

3、栈(线程私有)

栈的作用:维护方法之间的调用关系(局部变量)

栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中

一个JVM进程中,可以有多个线程,每一个线程都包含一个栈

4、程序计数器(线程私有)

程序计数器的作用:用来记录当前线程执行的行号的。 程序计数器是一块比较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器。

一个JVM进程中,可以有多个线程,每一个线程都包含一个程序计数器

举例:

public class test {
    public int a; // 全局变量(也可叫做test这个类的成员变量)
    public static int b; // 静态变量
    public void method() {
        int c = 0; // 局部变量
        System.out.println("这是test这个类的一个普通成员方法");
    }
    public static void run() {
        System.out.println("这是一个静态方法!"); // 静态方法不需要借助实例化对象
    }
    public static void main(String[] args) {
        test test1 = new test(); // test1 与 test2 是引用类型,也是局部变量
        test test2 = new test(); // new test是一个实例化对象
    }
}

堆中存放的有:全局变量a、成员方法method、new test()

栈中存放的有:局部变量c、test1、test2

方法区中存放的有:静态变量b、静态方法run

JVM类加载机制

类加载可以理解为把.class文件从文件 (硬盘) 被加载到内存 (元数据区) 的过程

加载

把.class文件找到,找到文件并把文件内容读到内存中去

在寻找.class文件的过程中,需要使用到双亲委派模型来寻找,双亲委派模型在下面文章讲解

验证

检查.class文件格式是否符合规范要求(JVM规范中明确描述了)

准备

给类对象分配内存空间(未初始化的空间,内存空间的数据是全0的)

类加载的目的就是得到类对象

解析

针对字符串常量进行初始化,也就是Java 虚拟机将常量池内的符号引用替换为直接引用的过程,也就是初始化常量的过程

具体解析过程如下:

 

初始化

针对类对象进行初始化(初始化静态成员、执行静态代码块,类要是有父类,还需要加载父类)

类加载机制是一个“懒加载”的策略(懒汉模式),非必要不加载,不是JVM一启动就把所有的.class都加载了。

必要时机进行类加载:

1、创建了这个类的实例

2、使用了这个类的静态方法/静态属性

3、使用子类会触发父类的加载

双亲委派模型

双亲委派模型的作用就是在进行加载过程中,找.class文件这个过程。

在JVM加载的过程中需要使用到类加载器,JVM里面内置了三个类加载器:

BootStrap ClassLoader     负责加载Java标准库中的类
Extension ClassLoader     负责加载一些非标准的但是Sun / Oracle扩展的库的类

Application ClassLoader   负责加载项目中自己写的类以及第三方库中的类

它们三者关系如下:

双亲委派模型的原理:当我们需要去加载一个具体类时,不会去扫描自己的目录,而是优先去扫描父类加载器,直到扫描到最后一个父类加载器。最后一个父类加载器若扫描到具体类就进行后续加载步骤,若没有扫描到就交给自己孩子来处理。

举例:若我们想要去加载"java.lang.String"这个类时,扫描过程如下:

 

按照双亲委派模型的规则来工作的最大目的是为了防止程序员自己写一个特殊类,把标准类库里面的类给覆盖了

双亲委派模型也是可以打破~~

你自己实现的类加载器,可以继续遵守~~也可以不遵守~~(Tomcat里针对webapp的类加载器就没遵守)

JVM垃圾回收机制(GC)

在JVM 内存区域中,

1、栈随着线程一起销毁,当方法调用完毕,方法的局部变量自然随着出栈操作就销毁了

2、程序计数器就是一个单纯存地址的整数,也是随着线程一起销毁

3、方法区(元数据区)存放的类对象,很少会卸载

4、堆(new 出来的对象)存放的是全局变量,因此GC回收的目标主要是堆,GC是以 对象 为单位进行释放


JVM垃圾回收机制主要分为2个阶段:

1、寻找:谁是垃圾

2、释放:把垃圾对象的内存给释放掉


1、寻找

一个对象判断是否是垃圾,只需要判断其是否有引用指向对象即可,若无引用指向对象,则该对象可以被视认为垃圾。

在垃圾回收机制中,对于如何判断一个对象是否有引用指向主要有2种方法:

1.引用计数法  (Python 、 PHP编程语言采用的这种方法)

2.可达性分析  (Java 采用的此方法)

在《深入理解Java虚拟机》这本书中,这两种办法都有提到。

  • 那么如果我们在面试中被问到:在垃圾回收机制中,判断对象是不是垃圾有哪几种方法?你可以说引用计数法和可达性分析两种方法
  • ​​​​如果问的是:在Java的垃圾回收机制中,如何判断对象是不是垃圾,你只需回答“可达性分析”就行。

引用计数法(Python、PHP采用)

引用计数法就是在对象里面安排一个额外的空间,保存一个整数,来记录指向该对象的引用个数。每个对象都有一个单独的计数器,不是每一个类独有。

若引用个数为0,说明该对象没有引用指向就可以便认为是垃圾

随着引用的增加,计数器就随着增加;引用的销毁,计数器就随着减少

当计数器为0时,则认为该对象没有引用了,可以当做垃圾进行回收

 

引用计数法的缺点:

1、需要额外安排空间来保存引用计数器,浪费内存空间

2、存在循环引用的情况,会导致引用计数的判定逻辑出错

 

可达性分析(Java采用)

可达性分析可以理解为是否可以达到访问这个对象。若能够访问到这个对象,则认为此对象不是垃圾,若不能到达该对象则认为此对象是垃圾,进行回收。

拿二叉树来举例,通过根节点root可以访问到整棵树的任意节点。

因此在进行可达性分析的时候,需要确定遍历到达的起点:

1)栈上的局部变量(每个栈的每个局部变量都是起点)

2)  常量池中引用的对象

3)方法区中静态成员引用的对象

        可达性分析,总的来说就是从所有的起点出发,看看该对象里又通过引用能访问到哪些对象,顺藤摸瓜把所有可访问到达的对象都遍历一遍(遍历的同时把对象标记成“可达”),剩下的自然就是“不可达的”。

        可达性分析克服了引用计数的两个缺点,但也有自己的问题:

1、消耗更多的时间,因此某个对象成了垃圾,也不一定能第一时间发现,因为在扫描过程中是需要消耗时间的

2、在进行可达性分析的时候,要顺藤摸瓜,一旦在这个过程中,当前代码中的对象的引用关系发生了变化,就十分麻烦(于是,为了更准确的完成这个顺藤摸瓜的过程,就需要让其他业务线程暂停工作,此时便引来STW问题)

2、释放

标记清除

复制算法

        

        复制算法的缺点:复制算法虽然解决了内存碎片问题,但也造成了如下问题:

                                1、内存利用率比较低

                                2、如果当前大部分对象都是需要保留的,只有少部分垃圾,此时复制的层本比较高

标记整理

         

分代回收

 

 

 

 

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

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

相关文章

入门力扣自学笔记276 C++ (题目编号:874)

874. 模拟行走机器人 题目&#xff1a; 机器人在一个无限大小的 XY 网格平面上行走&#xff0c;从点 (0, 0) 处开始出发&#xff0c;面向北方。该机器人可以接收以下三种类型的命令 commands &#xff1a; -2 &#xff1a;向左转 90 度 -1 &#xff1a;向右转 90 度 1 < …

【数据库高阶语句】

文章目录 MySQL高阶语句一、常用查询1、按关键字排序 二、实操1.创建表2.排序查询&#xff08;默认不指定是升序排序&#xff0c;后面跟desc是降序排序&#xff09;3.order by还可以结合where进行条件过滤&#xff0c;筛选地址是杭州的学生按分数降序排列4.查询学生信息先按兴趣…

走访慰问空巢老人,连接传递浓浓温情

为了弘扬中华民族尊老、敬老、爱老的优良传统&#xff0c;让老人们感受到政府和社会的温暖&#xff0c;在“端午”来临之际&#xff0c;思南县青年志愿者协会联合思南县民慈社会工作服务中心、思南县小荧星幼儿园、思南县小英豪幼儿园到大河坝镇天坝村开展“走访慰问空巢老人&a…

阿里云短信服务API怎么调用

今天来搞一下阿里云短信服务来实现发送短信功能&#xff0c;其实能提供短信发送服务的平台有很多&#xff0c;但这里我选择的是阿里云&#xff0c;因为阿里云的示例还有代码封装的很简洁&#xff0c;使用起来非常简单&#xff0c;上手非常快&#xff0c;那么费话不多说我们直接…

Python案例|使用卷积网络对星系图片进行分类

星系动物园&#xff08;galaxy zoo&#xff09;是由牛津大学等研究机构组织并邀请公众协助的志愿者科学计划&#xff0c;目的是为超过100万个星系图像进行分类。这是天文学中一次规模浩大的公众星空普查活动&#xff0c;大众参与热情高涨&#xff0c;在近十万名志愿者的积极参与…

libevent:windows环境配置+QT使用

目录 libevent是什么 编译 QT使用 测试代码 libevent是什么 Fast portable non-blocking network programming with Libevent http://www.wangafu.net/~nickm/libevent-book/TOC.html 这篇文档讲的很清楚&#xff0c;尤其是Chapter 1: A tiny introduction to asynchro…

c++11 标准模板(STL)(std::basic_istream)(十二)

定义于头文件 <istream> template< class CharT, class Traits std::char_traits<CharT> > class basic_istream : virtual public std::basic_ios<CharT, Traits> 类模板 basic_istream 提供字符流上的高层输入支持。受支持操作包含带格式的…

【C++】vector 模拟笔记

文章目录 成员变量和迭代器reserve()函数易错点迭代器区间初始化易错点迭代器失效整体代码 成员变量和迭代器 下面有vector 存储示意图&#xff1a;vector 是一个左闭又开的空间&#xff0c;_finish 不能存储有效数据。vector 的 iterator 是T 类型的指针&#xff0c;不要认为 …

Python自动获取字母站视频

如果有疑问的话可以在我的谈论群&#xff1a;706128290 来找我 目录 前言 二、编写代码 1.引入库 2.编写主类 3. 自动获取cookies值和生成headers 4.获取命令行参数 运行效果 前言 browser_cookie3 第三方模块 browser_cookie3是browser_cookie模块的分支&#xff0c;…

Asymmetric Gained Deep Image Compression With Continuous Rate Adaptation文献复现

前言 相关论文阅读自行解决,这里主要是记录代码的学习与实验的复现 github地址 此代码非官方部署代码,而是私人实现的。 本博客仅做学习记录。 1 代码学习 1.1 主要框架部分 这里的主编解码器与高斯建模的方式,采用的是同joint上下联合自回归一样的方式,主要的改动在增益…

【Linux】使用云服务器搭建Linux环境

目录 1.Linux是什么 2.Linux的环境搭建 3.使用Xshell登录主机 1.Linux是什么 Linux&#xff0c;全称GNU/Linux&#xff0c;是一套免费使用和自由传播的类Unix操作系统&#xff0c;是一个基于POSIX的多用户、多任务、支持多线程和多CPU的操作系统。 简单来说&#xff0c;Lin…

图文详解Java参数传递类型

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

Linux用户和用户组

Linux是多用户、多任务操作系统 一般来说&#xff0c;一个服务分配一个用户&#xff0c;这个用户只拥有这个服务相关文件的相关权限&#xff0c;如果用户不需要登陆&#xff0c;连密码都可以不分配&#xff0c;一般来说&#xff0c;非法分子都是获取当前进程的的权限来攻击服务…

自然语言处理: 第五章Attention注意力机制

自然语言处理: 第五章Attention注意力机制 理论基础 Attention&#xff08;来自2017年google发表的[1706.03762] Attention Is All You Need (arxiv.org) &#xff09;&#xff0c;顾名思义是注意力机制&#xff0c;字面意思就是你所关注的东西&#xff0c;比如我们看到一个非…

vue3中echarts的使用

效果&#xff1a; 代码&#xff1a; <div class"outcharbox"><a-row :gutter"10"><a-col :span"8" v-for" (item, index) in linesobjdata" :key"item.MonitorItemId"><monitoringItemsChart :colorI…

49天精通Java,第40天,jd-gui反编译class文件,解决jd-gui中文乱码问题

目录 专栏导读一、添加局部变量二、反编译class文件三、解决乱码问题四、产品经理就业实战1、内容简介2、作者简介 专栏导读 本专栏收录于《49天精通Java从入门到就业》&#xff0c;本专栏专门针对零基础和需要进阶提升的同学所准备的一套完整教学&#xff0c;从0开始&#xf…

【SQL应知应会】表分区(四)• MySQL版

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 本文收录于SQL应知应会专栏,本专栏主要用于记录对于数据库的一些学习&#xff0c;有基础也有进阶&#xff0c;有MySQL也有Oracle 分区表 • MySQL版 前言一、分区表1.非分区表2.分区…

系统学习Linux-SSH远程服务(二)

概念 安全外壳协议&#xff0c;提供安全可靠的远程连接 特点 ssh是工作在传输层和应用层的协议 ssh提供了一组管理命令 ssh 远程登陆 scp 远程拷贝 sftp 远程上传下载 ssh-copy-id ssh keygen 生成 提供了多种身份验证机制 身份验证机制 密码验证 需要提供密码 密…

vue element select下拉框回显展示数字

vue element select下拉框回显展示数字 问题截图&#xff1a; 下拉框显示数字可以从数据类型来分析错误&#xff0c;接收的数据类型是字符串&#xff0c;但是value是数字类型 <el-form-item prop"classifyLabelId" :label"$t(item.classifyLabelId)"…

051、事务设计之TiDB事务实现方式

事务在TiDB中的存储 分布式事务 提交的第一阶段&#xff0c;会用三个CF 来存放这些数据信息&#xff0c; 一类列簇对应一类键值对&#xff0c; 第一个CF(default)存放的是数据 的键值对。第二个存放的是锁信息。 第三个对应的是提交信息。 put<3_100,Frank> 3_100: prim…