《JavaEE初阶》JVM基础知识

news2024/11/24 17:29:03

《JavaEE初阶》JVM基础知识

文章目录

  • 《JavaEE初阶》JVM基础知识
    • JVM内存区域划分
      • 堆:
      • 栈:
      • 方法区:
      • 程序计数器:
      • 划分细节:
    • 类加载机制:
    • 双亲委派模型:
    • 垃圾回收机制(GC)
      • 什么样的内存需要GC来回收
      • 引用计数来判断对象是否是垃圾:
      • 使用可达性分析来判断对象是否为垃圾:
      • 垃圾回收策略:
        • 有缺陷的垃圾回收策略:
        • JVM使用的分代回收策略:

本章主要介绍JVM中比较重要的三个内容:

  • JVM内存区域划分

  • JVM类加载机制

  • JVM垃圾回收机制

JVM内存区域划分

当我们创建一个java进程时,启动时会向操作系统申请一块内存,JVM会将这块内存划分为几个区域: 堆 栈 程序计数器 方法区

堆:

堆上主要存放的是new的对象,是最重要的区域,也是内存划分最多的区域.

栈:

栈上主要存放 方法之间的调用关系(不记录方法的主要内容,只记录方法之间的调用关系),局部变量

JVM中的栈分为java虚拟机栈和本地方法栈,java虚拟机栈是java代码使用的栈,而本地方法栈主要存放JVM内部使用的C++代码,(我们在阅读源码时,可以看到native方法,这类方法就是由JVM内部通过C++来实现的).但是在java1.8中,将这两块区域进行合并.

方法区:

方法区中主要存放 类对象

类对象: 类对象是我们在编写代码中,类的代码以及类中的静态变量与静态方法,这都属于类对象中的内容.

class student{
    int a;            //对象内容  每个对象都有一份a
    static int b;    // 类对象内容  所有对象共用一份b
}

程序计数器:

这个区域主要存放 下一条指令 的地址,这块区域内存划分最小的区域.

划分细节:

方法区和堆,在整个java进程中,只有一份,而栈和程序计数器是每一个进程都具有的.

在这里插入图片描述

类加载机制:

对于一个java程序,JVM通过类加载机制了类的生命周期:

在这里插入图片描述

分为以下三个大的步骤:

  • 加载:

    java程序打开.class文件,将.class文件转化为二进制的字节流,将这个二进制字节流的静态存储结构转化为方法区运行时的数据结构.在内存中生成一个代表这个类java.lang.class对象

  • 链接:

    1. 验证:

      检查.class文件格式是否符合规范要求

    2. 准备:

      给静态变量分配内存空间,并将其值填充为 0 值

    3. 解析:

      将字符串常量进行初始化, “符号引用替换为直接引用”

      在编译过程中,编译器会通过一些特殊的符号来代表这些字符串常量,在进行类加载时,将真正的字符串常量存放到对应内存中.

  • 初始化:

    针对类的静态成员进行初始化,执行静态代码块.

双亲委派模型:

描述的是类加载阶段,JVM去那些目录下寻找.class文件.

JVM自带的三个类加载器:

  • BootStrapClassLoader 负责加载标准库中的类

  • ExtensionClassLoader 负责加载一些扩展的类

  • ApplicationClassLoader 负责加载本地程序中的类

双亲委派模型就是在上述体系中实现的:
在这里插入图片描述

双亲委派模型能够巧妙地避免我们在本地程序中写出一个特殊的类,导致将方法库中的类给覆盖掉.例如我们写了个java.lang.String…

垃圾回收机制(GC)

在我们学习C语言的时候,我们知道C语言中申请内存是需要手动通过free来释放的.对于需要程序员手动释放内存,是容易造成内存泄露的.

JVM为java实现了自动化进行内存释放,也就是垃圾回收机制(GC)

什么样的内存需要GC来回收

在了解GC之前,我们需要了解什么样的内存需要被回收:

对于程序计数器而言,每一个进程中都具有一个程序计数器,所以我们不需要进行GC,直接跟随进程销毁即可

对于栈而言,栈中主要存储的是局部变量,我们已经约定了局部变量在出了其作用域就可以会被回收, 所以也不需要GC.

对于方法区而言,其主要任务是进行类加载,很少设计到"类卸载",所以对于GC的使用并不是很急迫.

对于堆而言,堆存储了许多new 对象, 这也意味着当很多对象使用完之后,是需要GC来清理内存的,故而堆是GC工作的主战场.

引用计数来判断对象是否是垃圾:

引用计数方案并不是java使用的方法.但我们也需要了解.

引用计数就是在一个对象中引入额外的计数器,这个计数器记录了有多少个引用指向了这个对象.如果计数器的值为0,说明该对象没有引用指向,则认为是垃圾,需要释放.

这个方案是具有很多缺陷的:

  1. 在多线程场景下需要考虑线程安全问题,(如果了解过多线程会很容易理解为什么有线程安全问题)

  2. 如果对象占用的内容较小,并且有多个时,会带来空间资源的浪费.(如果对象是2kb,引入计数器后变成了4kb,负担就翻倍了)

  3. 循环引用问题:

    class Test{
        Test ref = null;
    }
    Test a = new Test();   
    Test b = new Test();
    a.ref = b;
    b.ref = a;
    

    在这里插入图片描述

    如果我们把a,b的引用销毁,我们想要的效果是 两个Test被销毁,但是事与愿违:

    在这里插入图片描述

    此时计数器为1,仍然不能销毁这个对象.

使用可达性分析来判断对象是否为垃圾:

可达性分析是java使用的方案.

可达性分析是通过一些特殊的变量为起点.从起点出发,看看哪些对象可以被访问到,如果可以呗访问到,则认为这个对象不是垃圾,如果不能访问到,则认为是垃圾.

可以树的构造思想来理解:

在这里插入图片描述

以A结点为起点,则认为对象BDEG不是垃圾,CF是垃圾.

可达性分析相比于引用计数,就不会占用额外的内存空间,也不会涉及到循环引用问题.

垃圾回收策略:

有缺陷的垃圾回收策略:

  1. 标记-清除策略:

    使用可达性分析,找到垃圾对象,直接将垃圾对象释放掉.

    在这里插入图片描述

    将图中的垃圾对象进行回收

    这个方案的确将内存释放了.但是也引入了一个很严重的问题,释放后的内存空间并不是连续的.即内存碎片问题.

  2. 标记-复制策略:

    使用可达性分析,找到垃圾对象,将要保留的对象复制到另一侧的内存空间.

    在这里插入图片描述

    这样就不会造成内存碎片问题,但是也导致了内存空间的不合理利用.使得内存空间的利用率大大降低.

  3. 标记-整理策略:

    使用可达性分析,找到垃圾对象,使用顺序表或者链表的思想将垃圾对象调整内存位置.解决内存碎片问题.

    这个方案可以提高内存的利用率,也可以解决内存碎片的情况,但是缺点也十分明显,搬运操作是O(n)时间复杂度,比较耗时.

上述操作都有各自的缺陷,但是JVM将上述方案进行了结合,使用分代回收方案来解决他们各自的缺陷:

JVM使用的分代回收策略:

将内存空间划分为以下三种区域:
在这里插入图片描述

采用以下方案来操作对象:

  1. 新new的对象放在伊甸区

  2. 伊甸区的对象是大概率撑不过第一轮GC的,如果伊甸区的对象撑过了第一轮GC,则将这个对象通过复制算法放在幸存区.

  3. 幸存区的对象经过又一轮GC,如果幸存区的对象撑过了这一轮GC,则将这个对象通过复制算法放入另一个幸存区.

  4. 当对象在幸存区经过多轮GC,依然没有被垃圾回收,则认为这个对象一时半会是不会被销毁的,所以将这个对象通过复制算法放到老年代.

  5. 对象在老年代空间中,也是需要经过GC,但是GC的频率大大降低,如果老年代中的对象被标记为垃圾对象,则使用标记整理方案来进行回收.(由于老年代被垃圾回收的频率不高,所以可以接受标记整理方案带来的时间开销.)

  6. 当有一个很大的对象时,是直接存入到老年代的.(JVM特殊规定)

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

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

相关文章

Windows中安装和使用Kafka

👏作者简介:大家好,我是Rockey,不知名企业的不知名Java开发工程师 🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦 📝联系方式:he18339193956&…

【大学物理实验】凸透镜焦距测定

文章目录 选择题选择题 (多选题) 光路调整与薄透镜焦距测定中用到的主要实验元件包括: A. 光具座 B. 薄凸透镜 C. 光源 D. 带有平面镜的像屏 正确答案: ABCD (多选题)光路共轴调节是将那些光学元件的几何中心调至等高: A. 光具座 B. 透镜 C. 光源 D. 带有平面镜的像屏 正确…

Pixea 5:Mac电脑看图软件

Pixea 5是一款适用于 Mac 平台的图像浏览和管理软件。 下面是关于 Pixea Mac 看图软件的简要介绍: 图像浏览:Pixea 提供快速、流畅的图像浏览功能,支持常见的图像格式,如JPEG、PNG、BMP、GIF等。您可以通过缩略图、列表视图或全屏…

万物的算法日记|第四天

笔者自述: 一直有一个声音也一直能听到身边的大佬经常说,要把算法学习搞好,一定要重视平时的算法学习,虽然每天也在学算法,但是感觉自己一直在假装努力表面功夫骗了自己,没有规划好自己的算法学习和总结&am…

IF: 25+ 单细胞转录组学揭示肝实质和非实质细胞系的早期出现

, 桓峰基因公众号推出单细胞生信分析教程并配有视频在线教程,目前整理出来的相关教程目录如下: Topic 6. 克隆进化之 Canopy Topic 7. 克隆进化之 Cardelino Topic 8. 克隆进化之 RobustClone SCS【1】今天开启单细胞之旅,述说单细…

dubbo 服务拆分和调用

序言:dubbo 是阿里巴巴开发的一款开源的java rpc 框架,也就是远程调用框架。本文将说明dubbo服务拆分的实现思路。 本文是基于黑马探花交友前置课程dubbo做出的笔记记录。 完整视频和资料 通过百度网盘分享的文件:黑马 链接:https://pan.bai…

win10家庭版找不到组策略gpedit.msc的解决方法

废话不多说, 直接上方法;注意的事项我会再后面讲到。 1、打开记事本 在记事本中保存如下批处理内容 echo offpushd "%~dp0"dir /b %systemroot%\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mu…

损坏的二进制文件会导致“程序太大而无法放入内存”

不知道你是否做过这样的小实验:将一个可执行文件的头部写入一些无效的数据,或者将一个根本不是可执行文件的大型文件的扩展名改为”.exe”,然后执行它(警告,请记得先保存好工作文件)。 文件不会如预期般那样执行,你会…

【Python 随练】不相同的三位数字

题目: 有 1、2、3、4 个数字,能组成多少个互不相同且无重复数字的三位数?在控制台输出出来。 简介: 在本篇博客中,我们将使用Python代码解决一个数学问题:如何使用数字1、2、3和4组合成互不相同且无重复…

Vue 常用指令

指令介绍 指令 : 带有 v- 前缀的特殊属性。 指令的作用 : 当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM 。 在整个vue的编写过程当中,只要带v-的,那么都是常用的vue的指令。 v-text v-text作用与双大花括号作用…

【已解决】“X-Content-Type-Options”头缺失或不安全

Appscan是一款安全漏洞扫描软件,由IBM公司研发,后又被卖给了印度公司HCL。 在web安全测试中,今天我们说下扫描结果中包含X-Content-Type-Options请求头header的缺失或不安全的时候,我们该如何应对。 风险:可能会收集…

华为OD机试真题 JavaScript 实现【猴子爬山】【2023 B卷 100分】,附详细解题思路

一、题目描述 一天一只顽猴想去从山脚爬到山顶,途中经过一个有个N个台阶的阶梯,但是这猴子有一个习惯: 每一次只能跳1步或跳3步,试问猴子通过这个阶梯有多少种不同的跳跃方式? 二、输入描述 输入只有一个整数N&…

使用Linux系统命令对后门端口进行查杀

第一步,打开网络拓扑,启动实验虚拟机,查看虚拟机IP地址: Centos Linux 第二步,进入靶机服务器CentOS Linux,调用实验环境。使用docker images命令查看靶机服务器上的Docker镜像环境,找到本次实…

《水经注地图服务》横向扩展部署说明

在地图服务器中,随着数据量的不断增大,可能会存在原有的存储设备空间不够的情况,或无法承受高并发请求的情况。 此时,我们就可以通过横向扩展部署,增加新的设备来进行分担缓减,从而达到动态扩展存储设备以…

华为流程体系:IPD流程框架(限制版)

目录 前言 详细内容 专栏列表 CSDN学院课程地址 前言 今天主要来谈谈 IPD 体系的主体框架所涉及的一些相关内容。 其实关于 IPD 体系,我在之前的文章或课程中都有过不同程度的讲解。 但是,由于这个体系所涉及的面是非常广泛的。 这个时候就必须通…

加固你的数据防线:避免成为SQL注入攻击的下一个目标

SQL注入是一种常见的Web应用程序安全漏洞,攻击者利用该漏洞通过构造恶意的SQL查询语句,以执行未经授权的操作或获取敏感数据。本文将介绍SQL注入的概念、攻击原理以及常见的防范方案,帮助开发人员和系统管理员加强对Web应用程序的安全性。 1、…

深入理解迭代器,笛卡尔积,from itertools import product 小白一看就会

文章目录 一、product()是什么?二、product()的具体使用案例代码详细分析 总结 一、product()是什么? 在Python中,product()是内置函数itertools提供的一个工具函数,可以计算多个可迭代对象的笛卡尔积。product()接受一个或多个可…

7、微服务组件gateway

1、引入gateway 在原来的项目中添加gateway模块 gateway是springcloud中的组件&#xff0c;所以要确保父项目的pom.xml中引入了springcloud 那么在gateway模块的pom.xml中引入gateway&#xff0c;如下&#xff1a; <?xml version"1.0" encoding"UTF-8&quo…

Jmeter集成到jenkins

Jmeter集成到Jenkins 序号 修改人 版本 创建日期 修改日期 备注 1 进击的雷神 V1.0 Jmeter集成到Jenkins. 1 软件下载... 4 一:环境配置... 4 1.JDK安装&#xff…

ADC动态指标

量化误差ADC输出-ADC模拟输入 量化噪声功率&#xff1a; 信噪比&#xff1a; 由于仅仅考虑了量化噪声&#xff0c;上式为ADC的SNDR所能达到的极限值 N8,SNDR_max50dB N12,SNDR_max74dB N16,SNDR_max98dB N20,SNDR_max122dB 实际ADC还需要考虑期间噪声和电路非理想特性&am…