简述JVM

文章目录

  • JVM简介
  • JVM运行时数据区
    • 堆(线程共享)
    • 方法区/元空间/元数据区(线程共享)
    • 程序计数器
  • JVM类加载
    • 类加载过程
    • 双亲委派模型
  • 垃圾回收机制(GC)
    • 判断对象是否为垃圾
      • 判断是否被引用指向
    • 如何清理垃圾, 释放对象?

JVM简介

JVM 是 Java Virtual Machine 的简称, 意为Java虚拟机.

虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统。

JVM运行时数据区

也就是JVM的内存布局

在这里插入图片描述

堆(线程共享)

保存程序中创建的对象

方法区/元空间/元数据区(线程共享)

存放被JVM加载的类信息(类对象), 常量, 静态变量(static), 即时编译器编译后的代码等数据

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

程序计数器

记录了当前线程执行的下一条指令的内存地址


class Test {public int n = 20;public static int a = 10;
}
public class Main() {public static void main(String[] arg) {Test t = new Test();}
}

n是普通的成员变量, 就包含在new的对象的内部, 存放在堆上

a是一个静态成员变量, 包含在类对象中, 存放在方法区中

t是一个局部变量, 存放在栈上

new Test()这个对象是保存在堆上的

栈上的t保存了堆上的new Test()的内存地址

JVM类加载

Java程序一开始是一个.java文件, 通过javac编译成.class文件, 运行java程序, JVM就会读取.class文件, 把文件的内容加载到内存中, 并构造成一个.class对象

类加载就是: 把类从硬盘文件加载到内存中.

类加载过程

流程:

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

  2. 验证: 检查当前.class文件是否符合标准格式

  3. 准备: 给类对象分配内存. 分配出来的内存空间, 内容就是全0的值.

  4. 解析: 将常量池内的符号引用替换为直接引用的过程, 也就是初始化常量的过程. 初始化类对象中涉及到的一些字符串常量, 这些字符串常量在.class文件中已经存在, 直接读到内存中就行.

    • 符号引用: 偏移量. 在.class文件中不知道字符串真实的内存地址在哪, 只知道一个相对的偏移量, 知道字符串的内容在.class文件的哪个地方.
    • 直接引用: 真实的内存地址
  5. 初始化: 对类对象进行更具体的初始化操作. 初始化金泰城园, 执行静态代码块, 加载父类…


双亲委派模型

实则单亲.

JVM加载.class文件的时候, 需要用到"类加载器"模块.

JVM中自带了三个类加载器:

  • Bootstrap ClassLoader: 负责加载标准库中的类
  • Extension ClassLoader(父亲是Bootstrap ClassLoader): 负责加载JVM扩展的库
  • Application ClassLoader(父亲是Extension ClassLoader): 负责加载第三方库.

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

当接收到类加载请求时:

  • Application ClassLoader是类加载的入口, 不会立即就搜索第三方库的目录, 而是先把任务委派给父亲, 让父亲先尝试加载.
  • 到了Extension ClassLoader, 也不会立即搜索扩展库的目录, 把任务委派给父亲, 让父亲先尝试加载.
  • 到了Bootstrap ClassLoader, 也不会立即搜索扩展库的目录, 把任务委派给父亲, 但是他没有父亲, 就只能自己来搜索了. 如果找到了这个类, 就会进行后续的加载流程; 如果没有, 那么任务就会交付给孩子来解决.
  • 如果任务回到了Extension ClassLoader, 他就要搜索扩展库的目录, 如果找到了这个类, 就会进行后续的加载流程; 如果没有, 那么任务就会交付给孩子来解决.
  • 如果任务回到了Application ClassLoader, 他就要搜索第三方库的目录, 如果找到了这个类, 就会进行后续的加载流程; 如果没有, 那么就抛出异常.

这样做的目的: 明确类的优先级(标准库的类最优先加载, 扩展库其次, 第三方库最低)

标准库中有一个类java.lang.String, 如果我们自己也写了一个java.lang.String类

JVM始终是加载标准库里的类, 而不会加载到我们写的类, 这样便可以避免程序员的代码对标准库的代码产生负面影响


类加载的时机?(类似于懒汉模式, 用到了才加载)

  1. 构造了这个类的实例
  2. 使用了该类的静态方法, 静态属性
  3. 子类的加载会触发父类加载.

垃圾回收机制(GC)

对于程序计数器, 栈而言, 它的生命周期与相关的线程有关, 随线程生, 随线程灭, 并且这两个区域的内存分配和回收具有确定性, 因为当方法或者线程结束了, 内存就自然跟着线程回收了. 所以垃圾回收主要是回收堆和方法区这两个区域.

缺点: 消耗额外的系统资源, 消耗一定的时间, 可能有STW问题

垃圾回收是以对象为单位进行回收

垃圾回收的流程分为两步: 1. 判定对象是否为垃圾. 2. 释放对象的内存

判断对象是否为垃圾

一个对象, 如果在后续代码中不会被继续使用到了, 就可以视作是垃圾了

  • 不会被继续使用: 没有被任何引用指向

    public void test() {T t = new T();t.func();
    }
    test();
    

    调用方法test的时候, 局部变量t被创建, 当test方法执行完了之后, t自然销毁, 此时new T()就没有被引用指向了, 这个对象也就是垃圾了.

判断是否被引用指向

  1. 引用计数

    给这个对象里面安排一个计数器, 每次有引用指向它, 就把计数器+1, 每次引用被销毁, 计数器-1, 当计数器为0, 意味着该对象就是垃圾了

    class Test {//
    }
    Test t = new Test();//new Test()里的计数器为1
    Test t2 = t;//new Test()里的计数器为2
    Test t3 = t2;//new Test()里的计数器为3
    t = null;//new Test()里的计数器为2
    t2 = null;//new Test()里的计数器为1
    t3 = null;//new Test()里的计数器为0, 此时该对象为垃圾了
    

    该方法并非是JVM中使用的方案, Python和PHP的虚拟机GC采用的是此方案

    缺陷:

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

    • 可能存在循环引用的问题, 导致对象不能正确识别为垃圾.

      class Test {public Test t;
      }
      Test a = new Test();//计数器为1
      Test b = new Test();//计数器为1
      a.t = b;//计数器为2
      b.t = a;//计数器为2
      a = null;//计数器为1
      b = null;//计数器为1
      

      在这里插入图片描述

      此时这两个对象的引用计数不为0, 不能被当做垃圾. 与此同时, 一想要使用对象1, 就需要访问对象2. 要想使用对象2, 就得先访问到对象1…这就是循环引用

  2. 可达性分析(JVM使用的方案)

    JVM首先会从现有代码中的能直接访问到的对象出发, 尝试便利所有能访问的对象, 只要对象能访问到, 就会标记成"可达", 完成整个遍历之后, 不可达的对象, 就相当于是垃圾了.

    这样的操作没有额外的空间开销, 但是消耗了更多的时间.

    那些是能直接访问到的对象呢?

    这些对象又被称为gc roots.

    1. 栈上的局部变量.
    2. 常量池里的引用
    3. 方法区中类静态属性引用的对象
    4. 本地方法栈中 JNI(Native方法)引用的对象

    代码执行过程中, 一个对象是否是垃圾, 往往是动态变化的(之前不是垃圾, 现在是垃圾了), 所以可达性分析的扫描是持续的周期性的

如何清理垃圾, 释放对象?

  1. 标记清除: 被标记为垃圾的对象直接清除.

    弊端: 申请内存的时候, 都是申请的连续的空间, 直接释放会导致内存的碎片化, 会破环原有的连续性, 可能会导致有内存, 但是申请不了.

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

    把一个内存分成两份, 一份使用, 一份等待有效对象被复制过来.

    弊端: 如果复制的对象多, 开销会很大, 而且内存利用率也不高, 相当于浪费了一般的内存.

  3. 标记整理: 类似于顺序表的删除元素操作.

    弊端: 这样的方式虽然解决了复制算法内存利用率低的问题, 但是搬运对象的成本也比较高.

  4. 分代回收: 采用分治的思想, 进行代的划分, 把不同生命周期的对象放在不同代上, 不同代上采用最适合它的垃圾回收方式进行回收.

    Java的对象大体分为两类: 1. 生命周期很长的; 2.生命周期很短的

    不同的对象的生命周期是不一样的. 因此, 不同生命周期的对象可以采取不同的收集方式, 以便提高回收效率.

    如何分代?

    JVM根据对象存活的周期(GC周期性扫描)不同, 把对内存划分了2块, 为新生代老年代.


    新生代又分为伊甸区(Eden)和幸存区(Survivor).

    伊甸区占大部分内存, 这里存储的对象生命周期都很短. 经过一次GC后, 存活下来的对象就会通过复制算法复制到幸存区.

    幸存区是两块大小相等的内存区域, 每次只用一块, 如果这里的对象经过GC后存货, 会继续被复制到另一块幸存区, 如此往复.如果一个对象在幸存区里经过了很多轮GC还存活, 证明它的生命周期很长, 那么它就会被复制到老年代.


    老年代的GC频率比新生代要低. 这里清理垃圾的策略是标记整理

    如果一个对象的体积很大, 那么他会直接进入老年代, 因为这样的对象不适合进行复制

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

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

相关文章

图解Kafka高性能之谜(五)

高性能网络模型NIO 简单架构设计: 详细架构设计: 高性能的磁盘写技术 高性能的消息查找设计 索引文件定位使用跳表的设计 偏移量定位消息时使用稀疏索引: 高响应的磁盘拷贝技术 批处理设计 请求亲和性设计 内存池高效、安全设计 高性能…

安防监控项目---boa服务器的移植

文章目录 前言一、boa服务器简介二、移植步骤三、测试结果四、A9平台移植BOA总结 前言 书接上期,在配置完成环境后,那么接下来呢还得移植两个非常关键的东西,一个呢时boa服务器,另一个呢时cgi接口,boa服务器能够使得我…

日常软件游戏丢失msvcp120dll怎么修复?分享5个修复方法

在计算机使用过程中,我们经常会遇到一些错误提示,其中之一就是“msvcp120dll丢失”。那么,究竟什么是msvcp120dll文件?当它丢失时,我们会遇到哪些问题呢?本文将从以下几个方面进行详细阐述。 msvcp120dll是…

线扫相机DALSA--采集卡Base模式设置

采集卡默认加载“1 X Full Camera Link”固件,Base模式首先要将固件更新为“2 X Base Camera Link”。 右键SCI图标,选择“打开文件所在的位置”,找到并打开SciDalsaConfig的Demo,如上图所示: 左键单击“获取相机”&a…

【python与数据结构】(leetcode算法预备知识)

笔记为自我总结整理的学习笔记,若有错误欢迎指出哟~ python与数据结构 Python 中常见的数据类型数据结构1.数组(Array)2.链表(Linked List)3.哈希表(Hash Table)4.队列(Queue&#x…

Postman的高级使用,傻瓜式学习【下】

目录 前言 1、全局变量、环境变量 1.1、概念: 1.2、如何设置全局变量、环境变量 1.3、获取全局变量、环境变量 1.4、案例1:手动设置变量,请求参数获取 1.5、案例2:代码设置变量,代码获取变量 2、Postman读取外部…

Android开发知识学习——HTTP基础

文章目录 学习资源来自:扔物线HTTPHTTP到底是什么HTTP的工作方式URL ->HTTP报文List itemHTTP的工作方式请求报文格式:Request响应报文格式:ResponseHTTP的请求方法状态码 HeaderHostContent-TypeContent-LengthTransfer: chunked (分块传…

[微信小程序踩坑]微信小程序editor富文本组件渲染字符串时,内部图片超出大小导致无法正常渲染或回显(数据传输长度为 3458 KB,存在有性能问题!)

坑一&#xff1a;回显问题 富文本组件&#xff1a; <editor id"editor" name"{{name}}" style"font-size: 28rpx;color: #C9CDD4" read-only"{{true}}" placeholder"{{placeholder}}" bind:input"onChange11"…

kaggle新赛:AI Village夺旗赛挑战

赛题名称&#xff1a;AI Village Capture the Flag DEFCON31 赛题链接&#xff1a;https://www.kaggle.com/competitions/ai-village-capture-the-flag-defcon31 赛题背景 夺旗赛这款广受欢迎的竞技游戏&#xff0c;不仅可以在户外进行。数字夺旗赛指的是一系列需要参赛者利…

Django 全局配置 settings 详解

文章目录 1 概述1.1 Django 目录结构 2 常用配置&#xff1a;settings.py2.1 注册 APP&#xff1a;INSTALLED_APPS2.2 模板路径&#xff1a;TEMPLATES2.3 静态文件&#xff1a;STATICFILES_DIRS2.4 数据库&#xff1a;DATABASES2.5 允许访问的主机&#xff1a;ALLOWED_HOSTS 1 …

AI与Prompt:解锁软件开发团队的魔法咒语,在复杂任务上生成正确率更高的代码

AI与Prompt&#xff1a;解锁软件开发团队的魔法咒语 写在最前面论文&#xff1a;基于ChatGPT的自协作代码生成将团队协作理论应用于代码生成的研究自协作框架原理1、DOL任务分配2、共享黑板协作3、Instance实例化 案例说明简单任务&#xff1a;基本操作&#xff0c;生成的结果1…

Linux系统下DHCP服务安装部署和使用实例详解(蜜罐)

目录 一、概述 二、具体配置如下&#xff1a; 一、概述 DHCP &#xff1a;动态主机设置协议&#xff08;英语&#xff1a;Dynamic Host Configuration Protocol&#xff0c;DHCP&#xff09;是一个局域网的网络协议&#xff0c;使用UDP协议工作&#xff0c;主要有两个用途&…

sql-50练习题0-5

sql练习题0-5题 前言数据库表结构介绍学生表课程表成绩表教师表 0-1 查询"01"课程比"02"课程成绩高的学生的信息及课程分数0-2查询"01"课程比"02"课程成绩小的学生的信息及课程分数0-3查询平均成绩大于等于60分的同学的学生编号和学生…

父子项目打包发布至私仓库

父子项目打包发布至私仓库 1、方法一 在不需要发布至私仓的模块上添加如下代码&#xff1a; <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-deploy-plugin</artifactId><configuration><skip>true</s…

基于OFDM的通信系统模拟实现

文章目录 前言一、OFDM 基本知识1、OFDM 理论知识及仿真2、OFDM 调制3、OFDM 解调 二、2ASK&#xff08;二进制振幅键控&#xff09;1、2ASK 基本原理①、OOK②、2ASK 2、2ASK/OOK 信号产生方法3、2ASK/OOK 信号解调方法 三、基于 OFDM 的通信系统模拟实现1、整体流程2、MATLAB…

基于nodejs+vue食力派网上订餐系统

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

行情分析——加密货币市场大盘走势(10.27)

目前大饼开始了震荡盘整&#xff0c;目前远离EMA21均线&#xff0c;预计会有大的回调动作。而MACD日线来看&#xff0c;昨日和今日开始呈现绿色空心柱&#xff0c;也在说明大饼在做震荡盘整。不排除大跌的可能性&#xff0c;大饼可以开始布局中长线空单&#xff0c;可以再35000…

【NLP】word复制指定内容到新的word文档

目录 1.python代码 2.结果 需求&#xff1a; 复制word文档里的两个关键字&#xff08;例如“起始位置”到“结束位置”&#xff09;之间的内容到新的word文档。 前提&#xff1a;安装win32包&#xff0c;通过pip install pywin32命令直接安装。话不多说&#xff0c;直接上代码…

苹果cms模板MXone V10.7魔改版源码 全开源

苹果cms模板MXone V10.7魔改版源码 全开源 苹果cms模板MXone魔改版短视大气海报样式 安装模板教程说明&#xff1a; 1、将模板压缩包上传到苹果CMS程序/template下解压 2、网站模板选择mxone 模板目录填写html 3、网站模板选择好之后一定要先访问前台&#xff0c;然后再进…

面试准备中........

一、Linux 计算机网络相关&#xff1a; 1.OSI七层模型 应用层 &#xff1a;给用户提供操作界面 表示层&#xff1a;数据的表示&#xff1a;将字符转化为2进制或将2进制转化为字符。加密&#xff1a;对称加密和非对称加密&#xff0c;ssh协议。压缩&#xff1a;将文件压缩。…