JVM知识扫盲篇

news2024/11/22 22:03:14

JVM扫盲

  • 一:故事背景
  • 二:知识点主要构成
    • 2.1 JVM为什么能跨平台
    • 2.2 JVM整体结构
      • 2.1 类加载子系统
        • 2.1.1 概述
        • 2.1.2 具体类加载器
        • 2.1.3 双亲委派机制
        • 2.1.4 Tomcat为什么要自定义类加载器
      • 2.2 运行时数据区
        • 2.2.1 整体概念
        • 2.2.2 程序计数器的作用
        • 2.2.3 虚拟机栈(Java栈、Java方法栈)
        • 2.2.4 本地方法栈
        • 2.2.5 堆以及堆中的各个区域作用
          • 2.2.5.1 概念:
          • 2.2.5.2 堆内存设置:
          • 2.2.5.3 堆初始化大小:
          • 2.2.5.4 新生代与老年代
          • 2.2.5.5 对象流转过程
      • 2.3 垃圾回收
        • 2.3.1 概念
        • 2.3.2 寻找垃圾对象方法
        • 2.3.3 垃圾回收算法
        • 2.3.4 常见的垃圾回收器
  • 三:总结提升

一:故事背景

最近在回顾JVM的基本知识,今天在这里总结一下,JVM的基础知识。方便之后再次进行回顾。

二:知识点主要构成

2.1 JVM为什么能跨平台

  1. JVM类似于软件。不同系统上的JVM是不一样的,但是却提供了相同的功能。
  2. JVM执行的是字节码文件,也就是.java 编译后生成的.class 文件。这样做的好处是可以很好的提高执行效率。
    在这里插入图片描述

2.2 JVM整体结构

jvm整体结构宏观如下,每一部分我都进行了表明,下面将会详细讲解,每一部分的作用。
在这里插入图片描述

2.1 类加载子系统

2.1.1 概述

类加载子系统主要分为三个步骤,分别是 加载、链接、初始化。其中链接最为重要。链接主要分为三个部分,分别是 验证、准备、解析。这里重点解释一下什么叫做:“将符号引用解析为直接引用”。
在Java里,Java类和其成员都表示为 符号引用。不涉及到具体的内存地址或者方法指针。当Java程序在JVM上运行的时候,符号引用要被解析为直接引用,以便在运行的时候可以正确的找到对应的类、方法、字段。
在这里插入图片描述

2.1.2 具体类加载器

Java中提供的类加载器主要分为 2类四种。

  1. 引导类加载器
    引导类加载器(BootStrapClassLoader),一般由C或者C++语言编写,直接与操作系统交互,我们一般不对齐进行操作
  2. 自定义类加载器
    Java提供了2中自定义类加载器,通过实现(ClassLoader类)进行实现,分别是 ExtClassLoader、APPClassLoader、加载器。不同的类加载器负责加载不同的目录。

2.1.3 双亲委派机制

在这里插入图片描述

  1. 作用:避免类重复加载、防止核心API被篡改。
  2. 概述:加载类的时候,先提交给其父类进行类加载。一直提交给 BootStrapClassLoader,如果都无法加载指定类,才由自己进行加载。

2.1.4 Tomcat为什么要自定义类加载器

JVM判断一个类是不是已经加载的逻辑是:类名+对应的类加载器实例
如果Tomcat直接使用APPClassLoader类进行加载类的话,会出现多个项目中同名的类无法进行加载的情况。
例如我们有项目A和项目B,项目A内有一个类其全称为com.test.Hello.class,项目B中同样有一个类为com.test.Hello.class。如果使用同一个APPClassLoader,会导致只能加载一个的情况。Tomcat针对这种情况为每个应用都设置了自己单独的类加载器 WebappClassLoader 这样两个应用中的Hello.class类都会分别进行加载,不会产生冲突。

2.2 运行时数据区

2.2.1 整体概念

在这里插入图片描述

根据上面颜色的不同,将其分成了线程共享和线程隔离的两大部分。其中方法区和堆是多个线程共享的。
方法栈和本地方法栈,程序计数器。都不会被多个线程共享。每个线程独立的进行管理,管理自己的方法的调用过程。

2.2.2 程序计数器的作用

  1. PC Register,程序计数寄存器,建成程序计数器。它是物理寄存器的抽象实现。用来记录待执行的下一条指令的地址。
  2. 其实程序控制流的指示器,循环、if else、异常处理、线程恢复,都依赖其完成。

2.2.3 虚拟机栈(Java栈、Java方法栈)

在这里插入图片描述
java方法执行的过程中,不停的将方法对应的栈帧压入栈中。执行完之后,将会将栈帧进行出栈。

  1. 什么是栈帧:
    2.
  • 局部变量表存储了定义的每个变量。
  • 操作数栈用来记录要进行操作的数。

这里给一个小例子,用来方便理解操作数栈

public static void main(String[] args) {
	int a = 10;
	int b = 20;
	int c = a+b;
}

在这里插入图片描述
在执行操作的时候,会先将树放到操作数栈内,然后根据不同的指令将操作数放入到局部变量表,不同的变量具体对应的变量内。

2.2.4 本地方法栈

概念:
在Java中定义,但是由其它语言实现的方法。例如:native method方法。

2.2.5 堆以及堆中的各个区域作用

2.2.5.1 概念:
  • JVM规范中规定所有的对象和数组都该存放在堆中,在执行字节码指令时,将创建的对象存入堆中,对象对应的引用地址存入虚拟机栈中的栈帧中。
  • 当方法执行完之后,创建的对象不会马上回收,而是等到jvm后台执行GC后,对象才会被回收。
2.2.5.2 堆内存设置:
  • -Xms:(memory start),用来指定初始化内存的大小。
  • -Xmx:(memory max),指定堆的最大内存大小。
  • 一般会把 -Xms和-Xmx的值设置为一样,这样Jvm在GC之后,就不需要去修改堆内的内存大小了

我们可以自己实践来查看指定的堆的大小
启动jar包:

java -XX:NativeMemoryTracking=summary -Xms1024m -Xmx1024m -jar  jar包路径 

使用jcmd命令查看

//1.jcmd 查看进程号
jcmd 
//2. 根据进程号查看堆的使用情况
jcmd 进程id VM.native_memory summary
2.2.5.3 堆初始化大小:
  • 初始化内存大小:物理内存/64
  • 最大内存大小:物理内存/4
2.2.5.4 新生代与老年代
  • 新生代存放的是刚刚创建的对象
  • 老年代存放的是经过多次GC之后,仍然存在的对象
  • 新生代与老年代默认的比例为 1:2 ,一遍不需要调整,除非明确知道存活时间较久的对象更多,则需要调大老年代占比。
2.2.5.5 对象流转过程

在这里插入图片描述

  • 新生代分为三块区域,分别是 Eden、S0、S1。三块区域,新对象创建出来,会先放到Eden区内,当进行一次Youg GC之后,剩余的对象将会转移到S0,并且增加一个GC次数的表示。在阈值到达之前,都会在S0-S1,反复转移。知道达到GC的阈值,才会进入老年代。
  • 如果创建的大对象,从Eden区域出来之后,无法放入 S0,S1,区域,对象在经历过一次GC之后,将会直接进入老年代。
  • 如果创建的是超大对象,无法放入Eden区的话,创建的对象将会直接存入老年代。

2.3 垃圾回收

2.3.1 概念

垃圾指的是JVM中,没有任何引用指向它的对象。如果不清理这些垃圾对象,那么它们就会一直占用内存,而无法给其他对象使用,最终垃圾对象越来越多,直到OOM。

2.3.2 寻找垃圾对象方法

引用计数法:

  • 每个对象都保存一个引用计数器属性,用户记录对象被引用的次数。
  • 实现起来简单,但是需要额外的空间来存储引用数,维护引用数。并且无法处理循环引用问题。
    可达性分析法:
    从GCRoot开始,寻找到可达对象,不可达的就是失去引用的对象。
    GCRoot:
  • 正在执行的方法的参数、局部变量引用的对象
  • 本地方法栈正在执行的方法的参数、局部变量所对应对象的引用
  • 方法区中保存的类的静态属性对应的对象引用
  • 方法区中保存的类信息中的常量属性对应的对象引用
    在这里插入图片描述

2.3.3 垃圾回收算法

标记-清除算法:

  • 非常基础,常用的垃圾回收算法。分为两个阶段。
  • 标记阶段:从GCRoot 开发遍历,找打可达对象,并且在对象头中标记
  • 清除阶段:堆内存空间进行线性遍历,如果发现对象头中未标记为可达对象,则进行回收
    在这里插入图片描述
  • 存在问题:效率不高,会产生内存碎片问题。由于回收过后,内存是不连续的,新加入的大的对象可能无法存放

复制算法:

  • 将内存空间分为两块,每次使用其中一块,在进行垃圾回收时,将可达对象复制到没有被使用的内存块中,然后再清除当前内存块的对象。后续按照相同的流程进行垃圾回收。
  • 这种算法解决了标记清除算法,存在的碎片问题。
  • 如果可达对象比较多,垃圾对象少,复制算法效率就比较低。其适合新生代的垃圾回收。
  • 始终有一半空间是空闲的。可能需要频繁修改栈内引用指向的堆内对象的地址。
    在这里插入图片描述

标记整理算法:

  • 结合了标记清除和复制算法的优点。首先标记可达对象,将所有存活对象移动到内存的一段,最后清理边界外所有空间。
    在这里插入图片描述

算法对比:

-标记-清除标记-整理复制
速度中能最慢最快
空间开销少(有碎片)少(无碎片)最多
移动对象

2.3.4 常见的垃圾回收器

在这里插入图片描述

三:总结提升

本文总结了Java的JVM虚拟机的整体结构,以及各个结构对应的大概功能,此文章正如标题所说,是属于扫盲篇。希望大家看完之后,能对整个JVM的整个结构,各个结构功能有想应的了解。如果大家感兴趣,还请持续关注我,接下来会更新一些JVM其它相关知识。

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

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

相关文章

MySQL - 数据库级别的外键

1. 外键 FOREIGN KEY (了解) 测试数据 : 学生表 CREATE TABLE IF NOT EXISTS student (id INT(4) NOT NULL AUTO_INCREMENT COMMENT 学号,name VARCHAR(30) NOT NULL DEFAULT 匿名 COMMENT 姓名,pwd VARCHAR(20) NOT NULL DEFAULT 123456 COMMENT 密码,sex VARC…

在 Mac 上安装 K8S

本篇文章将介绍如何在 Mac 上使用 minikube 搭建单机版的 Kubernetes。 安装步骤 安装 Docker 安装 docker 主要是用于提供容器引擎。直接下载安装即可。 下载地址 安装 Kubectl 推荐使用 home brew 安装 brew install kubectl可以使用下面的命令查看是否已经安装完毕 …

MAYA粒子圈

无法修改 完成一圈的时间

【C51】基于51单片机的自动输液监控系统设计与实现

摘 要 随着科技进步,我国的医疗设施不断完善,逐渐达到现代化水平。在当今的医疗环境下,病患更关心自己是否能够及时进行有效的治疗,医护人员对患者进行输液过程的全程监控。医生治疗的效果明显提高,不仅节约大量的时间…

Linux: 进程管理

一,快速上手,结束一个失控的进程 在主目录中,用文本编辑器创建一个文本文件badpro,如下: #! /bin/bash while echo "Im making files!!" domkdir adircd adirtouch afilesleep 2s done将该文件设定为可执行…

Leetcode 刷题 动态规划 子序列问题

300. 最长递增子序列 首先明确什么是子序列 子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序 不一定要连续 可以删除部分元素 但是要保证相对顺序 1. dp[i]的定义 dp[i]表示i之前包括i的以nums[i]结尾的最长…

Hutool 30

Hutool是一个Java工具包,提供了丰富的工具类库和简化开发的工具方法。它的目标是提供一套丰富、实用、高效和易用的Java工具类,以提升开发者的开发效率和开发质量。以下是Hutool的一些主要特点和功能模块: 常用工具类:Hutool提供了…

【Linux | Shell命令】bash shell 进程、磁盘、排序命令

目录 一、概述二、进程相关命令2.1 ps 命令 三四五 一、概述 上篇文章 bash shell 基础命令 中,介绍了一些与目录、文件相关的 shell 命令,本文继续介绍其他与进程、磁盘、排序、归档相关的命令,读者可以在自己的Linux系统下,实操…

【AI赋能未来】一文带你了解生成对抗网络(GAN)

自我介绍⛵ 📣我是秋说,研究人工智能、大数据等前沿技术,传递Java、Python等语言知识。 🙉主页链接:秋说的博客 📆 学习专栏推荐:MySQL进阶之路、C刷题集、网络安全攻防姿势总结 欢迎点赞 &…

shiro框架 02使用shiro进行用户的认证

01.shiro框架的具体业务: 具体的内部结构: Subject(主体):与软件交互的一个特定的实体(用户、第三方服务等)。 SecurityManager(安全管理器) :Shiro 的核心,用来协调管理组件工作。 其中的: Au…

小研究 - Java 指针分析综述(二)

近年来静态程序分析已成为保障软件可靠性、安全性和高效性的关键技术之一. 指针分析作为基 础程序分析技术为静态程序分析提供关于程序的一系列基础信息,例如程序任意变量的指向关系、变量 间的别名关系、程序调用图、堆对象的可达性等. 介绍了 Java 指针分析的重要…

亚马逊云科技积极探索多样化生态合作模式,助力实现可持续发展愿景

2023年6月26日,亚马逊云科技中国峰会在上海世博中心盛大开幕!以主题“因构建 而可见”为大家拉开帷幕。当前,越来越多的企业客户,以及当地政府监管机构对企业的要求,都需要企业告知碳足迹,亚马逊云科技提供…

优盘数据恢复怎么做?3个方法分享!

我的优盘里保存了很多有纪念意义的照片,但是刚刚将u盘插入电脑后,发现有些照片已经损坏了。我想将优盘里的数据恢复,有什么靠谱的方法吗?给我推荐一下吧! 优盘是一种便携式存储设备,常用于存储和传输数据。…

Java-API简析_java.lang.Thread类(基于 Latest JDK)(浅析源码)

【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://blog.csdn.net/m0_69908381/article/details/131467981 出自【进步*于辰的博客】 因为我发现目前,我对Java-API的学习意识比较薄弱…

九类AI应用和五个简单LLM的Prompt技巧

一、九类AI应用 AI艺术:造梦日记、MidJourney、Stable Diffusion、Adobe、Stability、Remove AI聊天:ChatGPT、Discord、文心一言、Google Bard、星火、Character.Al AI社区:Kaggle、Hugging Face、H20、Github、Replicate、OpenCV AI创造…

chatgpt赋能python:Python随机打乱列表:如何使用Python打乱您的数据?

Python随机打乱列表:如何使用Python打乱您的数据? 在数据处理中,列表是一种常见的数据结构。然而,当数据量很大时,列表的排序方式也变得重要。为了更好地处理数据,我们需要知道如何使用Python打乱列表。 …

k8s操作命令

系列文章目录 文章目录 系列文章目录一、k8s基础命令1.陈述式资源管理方法:2.基础命令 总结 一、k8s基础命令 1.陈述式资源管理方法: 1.kubernetes 集群管理集群资源的唯一入口是通过相应的方法调用 apiserver 的接口 2.kubectl 是官方的CLI命令行工具…

项目——学生信息管理系统2

目录 用户类型,我们创建一个枚举类 在 org.xingyun.model 包下创建 UserType 枚举类 快速生成 get set 方法 修改代码,下拉框的内容,用我们的枚举类型 给登录按钮绑定事件 我们在 org.xingyun.utils 包下创建一个工具类 Eclipse 智能提…

【Java基础】volatile关键字

关于作者:CSDN内容合伙人、技术专家, 从零开始做过日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。 目录 一、导读二、概览2.1 作用2.2 多线程共享变量的访问流程2.3 多线…

EMC学习笔记(十二)跨分割区及开槽的处理

跨分割区及开槽的处理 1.开槽的产生1.1 对电源/地平面分割造成的开槽1.2 通孔过于密集形成开槽 2.开槽对PCB板EMC性能的影响2.1 高速信号与低速信号的面电流分布2.2 分地的概念2.3 信号跨越电源平面或地平面上的开槽的问题 3.对开槽的处理3.1 需要严格的阻抗控制的高速信号线&a…