当前位置: 首页 > news >正文

JVM简单了解

一、JVM概述

目录

一、JVM概述

1.jvm的作用

2.jvm的组成

2.1类加载

2.1.1加载

2.1.2链接

2.1.3初始化

2.1.4类加载器分类

2.1.5双亲委派机制

2.2运行时数据区

2.2.1程序计数器

2.2.2虚拟机栈

2.2.3本地方法栈

2.2.4java堆内存

2.2.5方法区

2.3本地方法库接口

 2.4执行引擎

2.4.1解释器

2.4.2JIT编译器

2.4.3半解释半编译

2.5垃圾回收

2.5.1早期的垃圾回收

2.5.2java的垃圾回收

2.5.3垃圾回收的区域

2.5.4垃圾回收算法

2.5.5垃圾回收器


1.jvm的作用

        将.class字节码文件装载,编译解释为该平台对应的机器码。jvm不仅可以加载java的字节码文件还可以加载其他语言的字节码文件。

2.jvm的组成

jvm的整体组成分为以下四个部分
        1.类加载器(ClassLoder)
        2.运行时数据区(Runtime Data Area)
        3.执行引擎(Excute Engine)
        4.本地库接口(Native Interface)

2.1类加载

        类加载系统从文件系统或网络中加载class文件,而是否可以运行由执行引擎决定。

2.1.1加载

        使用流将硬盘上的字节码读取到内存中(运行时数据区)的方法区中,生成对象的class对象

2.1.2链接

        验证:验证字节码格式是否正确,检查class字节码文件是否被篡改

        准备:为静态变量赋默认值,如static int a = 123;此时a被赋予int类型默认值0;

        解析:将字节码中符号引用替换成直接引用,(符号引号就是字节码中的逻辑符号,直接引用就是内存地址)

2.1.3初始化

                                        当类完成初始化,即代表这个类加载完成。

        初始化过程中主要有以下功能,1.初始化类中静态变量;2.执行静态代码块;如果有父类,则从父类开始递归初始化。初始化过程中是在执行底层构造方法<client>(),该方法是由编译器生成的。

什么时候初始化?(即类什么时候被加载)

        1.使用类中的静态成员,如调用类中的静态方法,静态变量
        2.运行类中的main方法
        3.new该类的对象
        4.加载该类的子类
        5.通过反射机制 Class.forName()

有以下两种情况不会被初始化

        1.使用类中的静态常量
        2.使用该类创建一个数组对象

2.1.4类加载器分类

引导类加载器(启动类加载器,bootstrap classloder)

        这个类加载器用语言和C++实现,嵌套在jvm内部,负责加载java核心库中的类。如java.lang、java.util、java.math、java.io、java.sql等包中的类。

扩展类加载器(extension classloder)

        这个类加载器由java语言实现,用于加载java8\jre\lib\ext 目录下的类

应用程序类加载器(application classloder)

        这个类加载器由java语言实现,用于加载我们自定义的类。

2.1.5双亲委派机制

        该机制是指在类加载过程中,会先由上级的类加载器进行加载,如果找不到该类,则逐级由下面的类加载器加载,如果找不到类则抛出ClassNotFoundException异常。该机制是必要的,可以有效地防止用户自定义的类因为地址名重复而覆盖源代码的类。

2.2运行时数据区

作用:运行时数据区是java程序运行时,jvm存储数据和管理程序执行的内存区域。

虽然各虚拟机的运行时数据区略有不同,但是都是满足java虚拟机的规范的,java8虚拟机规定,运行时数据区包括以下区域:1.方法区;2.堆;3.程序计数器;4.本地方法栈;5.虚拟机栈

2.2.1程序计数器

作用: 程序计数器是用来记录当前线程中执行的指令的位置

程序计数器特点:

        程序计数器是用来记录当前线程中执行的指令的位置,因此每个线程都有一个程序计数器,程序计数器是线程私有的;
        程序计数器占用内存小,执行速度快;
        程序计数器随线程而生,随线程而死;
        程序计数器不存在内存溢出的情况。

2.2.2虚拟机栈

作用:虚拟机栈是java执行方法的区域

虚拟机栈的特点:

        虚拟机栈中程序可以执行java方法,属于运行结构,每个线程都会有一个虚拟机栈,因此虚拟机栈也是线程私有的。
        当栈中执行的方法过多时,会出现栈溢出异常。
        栈运行特点,先进后出/后进先出
        方法被调用过后,在栈中称为栈帧,栈帧内部包括局部变量表,表达式栈,方法返回地址
                局部变量表中存储方法中的参数和方法内部的局部变量,基本数据类型直接存值,引用类型则存储对象的引用。
                表达式栈进行方法中的所有计算过程。
                当一个方法执行完毕之后,要返回之前调用它的地方,因此在栈帧中必须保存一个方法返回地址

2.2.3本地方法栈

作用:本地方法栈主要用来运行被调用的本地方法(用native修饰的方法,由操作系统实现的c++/c语言方法)

2.2.4java堆内存

作用:堆是用来存储运行时产生的所有对象。

堆的特点:

        堆是java内存管理的最大区域,是jvm中内存最大的区域。堆的内存大小是可以调节的(运行时数据区中除了程序计数器的大小不可以调整以外,其他均可以通过jvm调优来调整大小)。例如:-Xms:10m(堆起始大小)-Xmx:30m(堆最大内存大小)。
        java产生的所有对象都在堆中存储
        所有的线程共享堆内存
        堆空间会发生内存溢出
        堆中是垃圾回收的主要区域

堆的空间分区:

        堆分为新生区和老年区,新生区又分为伊甸园区和幸存者区,幸存者区又分为幸存者0区和幸存者1区。
        对象在堆中的分配过程:新产生的对象首先存放在伊甸园区,在第一次GC后,所有未被回收的对象会被转移到幸存者0区;在第二次GC后,伊甸园区和幸存者0区的所有对象会被转移到幸存者1区;再次进行GC后,伊甸园区和幸存者1区的所有对象都会转移到幸存者0区,如此循环往复,直到对象的GC次数超过15次,就会被转移到老年区,老年区的对象就相对稳定,GC的频率会较低。或者当对象较大时也会被送到老年区。
        堆空间分区的必要性:对堆空间进行分区是必要的,通过对对象在堆中进行分区,来调整GC对对象的扫描频率,从而提高GC的效率。

        设置堆空间的参数:
        -Xms:初始堆空间内存
        -Xmx:最大堆空间内存
        -Xmn:设置新生代的大小
        -XX:MaxTenuringTreshold:设置新生代垃圾的最大年龄

2.2.5方法区

作用:方法区主要用来储存加载到内存中的类信息,也会存储静态方法和变量及即时编译器编译的代码

方法区特点:
        
方法区物理上和堆处于同一个空间,但是逻辑上会对其进行区分,我们又称方法区为元空间
        方法区大小是可以设置的,通过对:MetaspaceSize=<N>参数进行修改, 方法区一旦空间不足,会触发FULL GC(整堆收集),会影响应用程序线程,一般情况下,可以把方法区设置较大一点
        方法区存在内存溢出
        方法区存在垃圾回收

方法区中的类什么时候会被回收?
    想要对方法区中的类进行回收,需要满足以下三个条件:
        1.方法区中该类及其所有子类的实例都不存在
        2.加载该类的类加载器不存在了
        3.该类的Class对象不存在了

2.3本地方法库接口

作用:本地库接口是一个编程框架,可以让java代码与其他语言编写的代码进行交互,即让java程序调用本地方法(c语言或c++)。

什么是本地方法:本地方法就是用native关键字修饰的方法

为什么要调用本地方法:本地方法可以与操作系统上的硬件进行交互,而java属于应用程序语言,没有权限操作硬件设备。

new Object().hashCode(); //public native int hashCode();  获取内存地址
new FileInputStream("").read();  //private native int read0() 读硬盘数据
new Thread().start();//    private native void start0(); 把线程注册到操作系统
 2.4执行引擎

作用:执行引擎(excution engine)的作用是将字节码文件解释/编译为对应平台上的机器语言。其充当了高级语言和机器语言之间的翻译官。

2.4.1解释器

        解释就是对字节码逐行解释成机器码的过程,该过程响应速度快,程序运行就可以投入使用,但是逐行解释效率较低。

2.4.2JIT编译器

        编译就是对字节码整体编译后执行,编译需要花费一定时间,但是效率高。JIT编译器会对热点代码进行编译后缓存,以后使用时就不需要进行编译操作了。

2.4.3半解释半编译

        java是半解释半编译语言,这样设计既可以在程序运行之处利用解释的特点立即执行,也能通过编译操作提升效率。

2.5垃圾回收

什么是垃圾:垃圾就是程序运行过程中没有任何引用能访问到的对象。
清理垃圾:如果不及时对垃圾进行清理,就会导致堆内存溢出。因为垃圾会一直占据内存知到程序运行结束。

内存溢出:内存溢出就是内存不够用了,但是还有新的对象产生,于是程序抛出异常。
内存泄漏:内存泄漏是因为某些对象程序已经不再使用了,但因为某些原因仍存在应用,GC无法对其进行回收,例如数据库连接对象,网络Socket对象。

Stop The World(STW):在GC过程中,会将应用程序的线程停止,发生短暂的卡顿。 

finalize机制:java中的Object类提供了一个finalize()方法,这个方法是在对象被判定为垃圾后,在被回收之前自动被垃圾回收器调用的方法。该方法是针对对象的,只能被调用一次。如果在第一次的finalize()方法中将本标记为垃圾对象复活(为其重新指向引用),则第二次垃圾回收时就不会调用finalize()方法了。

对象的分类:
        1.可触及:没有被判定为垃圾对象
        2.可复活:被判定为垃圾对象,但是还没调用过finalize()方法。
        3.不可触及:第二次被判定为垃圾对象。

2.5.1早期的垃圾回收

        早期的C和C++都是手动申请内存,手动释放内存。此种设定可以精确地管理内存,使用时申请,不需要时就释放。但是会给程序员带来较大的负担,一旦忘记释放内存,就会产生内存泄漏。

2.5.2java的垃圾回收

        java采用的是自动垃圾回收,解放了程序员,不用再关心什么时候释放空间。

2.5.3垃圾回收的区域

        堆是垃圾回收的重点区域,对堆中的新生代会频繁进行GC操作,较少对老年区GC。方法区因为类加载信息回收较为苛刻,需要等到FULL GC(整堆回收)。

2.5.4垃圾回收算法

2.5.4.1垃圾标记阶段的算法

1.引用计数算法(Reference Counting)
        
对每个对象都有一个引用计数的属性,当引用计数为0时,表示该对象已不存在引用指向他,便标记为垃圾。然而该方法有个致命缺点,就是无法解决循环引用问题,从而导致内存泄漏。

2.可达性分析算法
       
该方法从活跃对象开始向下寻找,与活跃对象相连接的都是被使用的,而未与活跃对象连接的就是垃圾对象。
        活跃对象包括:
                1.虚拟机栈中方法使用的对象;
                2.引用类型静态变量

static Object globalVariable = new Object(); // 静态变量是GC Root

                3.所有被同步锁持有的对象
                4.jvm内部的引用对象,如常驻的异常对象,类加载器等。

2.5.4.2正式回收阶段算法

1.标记复制算法:
        标记复制算法可以有多个内存空间,会将区域中的有用对象集体复制到其他区域中,然后将原本区域中的对象全部清除。通常适用于回收新生区。因为新生区中垃圾较多,需要复制的对象较少。

2.标记清除算法

        该算法只需要一块内存,会将被标记为垃圾的对象直接清除,但是回收后会导致内存碎片化,适用于老年区,老年区中垃圾较少。

3.标记压缩算法

        该方法只需要用到一块内存,会将被标记的对象删除后,再对剩余对象进行移动,防止产生碎片化区域。

分代收集

年轻代的对象,存活的少,垃圾多,使用标记复制算法进行回收
老年代的对象大,且存活时间长,采用标记清除和标记压缩算法进行回收
优化垃圾回收效率

2.5.5垃圾回收器

1.分类:

垃圾回收器按线程数分为:
        单线程(串行)Serial
        多线程(并行)Parallel 垃圾回收器。

 从工作模式上分为:
        独占式的: 当垃圾回收线程在执行时,其他用户线程暂停(STW)
        并发式的: 垃圾回收线程和用户线程可以同时执行, 减少了用户线程暂停的次数和时间,并未完全不存在STW。

按照工作内存分为:
        新生代垃圾收集器
        老年代垃圾收集器

jdk8支持的垃圾回收器:

相关文章:

JVM简单了解

一、JVM概述 目录 一、JVM概述 1.jvm的作用 2.jvm的组成 2.1类加载 2.1.1加载 2.1.2链接 2.1.3初始化 2.1.4类加载器分类 2.1.5双亲委派机制 2.2运行时数据区 2.2.1程序计数器 2.2.2虚拟机栈 2.2.3本地方法栈 2.2.4java堆内存 2.2.5方法区 2.3本地方法库接口 …...

【CSS—前端快速入门】CSS 选择器

CSS 1. CSS介绍 1.1 什么是CSS? CSS(Cascading Style Sheet)&#xff0c;层叠样式表&#xff0c;用于控制页面的样式&#xff1b; CSS 能够对网页中元素位置的排版进行像素级精确控制&#xff0c;实现美化页面的效果&#xff1b;能够做到页面的样式和 结构分离&#xff1b; 1…...

【MYSQL数据库异常处理】执行SQL语句报超时异常

MYSQL执行SQL语句异常&#xff1a;The last packet successfully received from the server was 100,107 milliseconds ago. The last packet sent successfully to the server was 100,101 milliseconds ago. 这个错误表明 MySQL 服务器与 JDBC 连接之间的通信超时了。通常由…...

【Day9】make/makeFile如何让项目构建自动化起飞

【Day9】make/makeFile如何让项目构建自动化起飞 使用make命令编写makefile文件依赖管理增量构建makefile注释&#xff1a;#makefile其他语法 make/makefile递归式工作过程 在Linux中&#xff0c;项目自动化构建是指使用一系列工具和脚本来自动执行软件项目的编译、测试、打包和…...

【单片机】嵌入式系统的硬件与软件特性

嵌入式系统的软件结构 嵌入式系统的软件结构一般分为 不带操作系统&#xff08;Bare Metal&#xff09; 和 带操作系统&#xff08;RTOS / Linux&#xff09; 两种。不同的软件架构适用于不同的应用场景&#xff0c;如 简单控制系统、实时控制系统、物联网、工业自动化等。 嵌…...

C语言学习笔记-初阶(30)深入理解指针2

1. 数组名的理解 在上一个章节我们在使用指针访问数组的内容时&#xff0c;有这样的代码&#xff1a; int arr[10] {1,2,3,4,5,6,7,8,9,10}; int *p &arr[0]; 这里我们使用 &arr[0] 的方式拿到了数组第⼀个元素的地址&#xff0c;但是其实数组名本来就是地址&…...

ROM修改进阶教程------修改安卓机型SELinux宽容的几种方式方法 以及第三方系统中如何关闭SELinux宽容

SELinux是一种强制访问控制安全机制,用于增强Linux系统的安全性。在某些情况下,可能需要对 SELinux 进行宽容设置,以满足特定的应用需求。当SELinux处于宽容模式时,系统允许违反安全策略的行为发生,但不会阻止这些行为,通常会在日志中记录这些违规事件。这与强制模式不同…...

亚马逊云科技Marketplace(中国区)上架专业服务产品, “云生态连接器”价值凸显

近日&#xff0c;由西云数据运营的亚马逊云科技Marketplace&#xff08;中国区&#xff09;正式支持专业服务产品。此次发布将大幅简化企业对云专业服务的采购流程&#xff0c;实现云软件从规划、部署到支持的全生命周期管理&#xff0c;同时也为合作伙伴提供了更多的销售机会。…...

【音视频】音频基础

一、音频基础 1.1 声音的物理性质 ——振动 声音是一种由物体振动引发的物理现象&#xff0c;如小提琴的弦声等。物体的振动使其四周空气的压强产生变化&#xff0c;这种忽强忽弱变化以波的形式向四周传播&#xff0c;当被人耳所接收时&#xff0c;我们就听见了声音。 1.2 声…...

策略模式的C++实现示例

核心思想 策略模式是一种行为型设计模式&#xff0c;它定义了一系列算法&#xff0c;并将每个算法封装在独立的类中&#xff0c;使得它们可以互相替换。策略模式让算法的变化独立于使用它的客户端&#xff0c;从而使得客户端可以根据需要动态切换算法&#xff0c;而不需要修改…...

本地部署pangolin获取谱系,从而达到预测新冠的流行趋势

步骤 1&#xff1a;安装Docker 注&#xff1a;此步骤忽略&#xff0c;可通过Docker官网对于文档进行安装,地址如下 Docker: Accelerated Container Application Developmenthttps://www.docker.com/ 步骤 2&#xff1a;拉取Pangolin镜像 docker pull staphb/pangolin:latest 步…...

【我的 PWN 学习手札】House of Emma

House of Emma 参考文献 第七届“湖湘杯” House _OF _Emma | 设计思路与解析-安全KER - 安全资讯平台 文章 - house of emma 心得体会 - 先知社区 前一篇博客【我的 PWN 学习手札】House of Kiwi-CSDN博客的利用手法有两个关键点&#xff0c;其一是利用__malloc_assert进入…...

4 Redis4 List命令类型讲解

Redis 列表&#xff08;List&#xff09;命令详解 1. Redis 列表&#xff08;List&#xff09;简介 Redis 列表&#xff08;List&#xff09;是一个简单的字符串列表&#xff0c;按照插入顺序排序。它可以用作 栈&#xff08;Stack&#xff09; 和 队列&#xff08;Queue&…...

CentOS 7 安装 Redis6.2.6

获取资源、下载安装 Redis6.2.6 安装Redis6.2.6 上传到服务器或直接下载&#xff08;wget http://download.redis.io/releases/redis-6.2.6.tar.gz&#xff09;、再解压安装 tar -zxvf redis-6.2.6.tar.gz 进入redis解压目录 cd redis-6.2.6先编译 make再执行安装 make PREFI…...

数据库原理4

1.数据库中的数据通常可分为用户数据和系统数据两部分。用户数据是用户使用的数据&#xff1b;系统数据称为数据字典。 2.SQL语言的功能&#xff1a;数据查询&#xff1b;数据操纵&#xff1b;数据定义&#xff1b;数据操作&#xff1b;数据控制 3.对未提交更新的依赖&#x…...

doris: MySQL

Doris JDBC Catalog 支持通过标准 JDBC 接口连接 MySQL 数据库。本文档介绍如何配置 MySQL 数据库连接。 使用须知​ 要连接到 MySQL 数据库&#xff0c;您需要 MySQL 5.7, 8.0 或更高版本 MySQL 数据库的 JDBC 驱动程序&#xff0c;您可以从 Maven 仓库下载最新或指定版本的…...

Django模型数据删除:详解两种方式

Django模型数据删除&#xff1a;详解两种方式 在Django框架中&#xff0c;数据模型&#xff08;Model&#xff09;不仅定义了应用的数据结构&#xff0c;还提供了与数据库交互的接口&#xff0c;包括数据的删除操作。本文将详细介绍两种在Django中删除数据的方式&#xff1a;通…...

C++并发以及多线程的秘密

1.基础概念 并发&#xff08;Concurrency&#xff09; 并发是指在同一时间段内&#xff0c;多个任务看起来像是同时执行的。并发并不一定意味着真正的同时执行&#xff0c;它可以是通过时间片轮转等方式在多个任务之间快速切换&#xff0c;让用户感觉多个任务在同时进行。并发…...

自学微信小程序的第十二天

DAY12 1、腾讯地图SDK是一套为开发者提供多种地理位置服务的工具,可以使开发者在自己的应用中加入地图相关功能,轻松访问腾讯地图服务和数据,更好地实现微信小程序的地图功能。 表49:search()方法的常用选项 选项 类型 说明 keyword string POI搜索关键词,默认周边搜索 l…...

⭐算法OJ⭐跳跃游戏【贪心算法】(C++实现)Jump Game 系列 I,II

既股票买卖系列之后的第二组贪心算法题目&#xff1a;跳跃游戏系列。这一篇介绍的两个问题&#xff0c;其输入均为一个数组&#xff0c;每个元素表示在该位置可以跳跃的最大长度。 55. Jump Game You are given an integer array nums. You are initially positioned at the …...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...

人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型

在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重&#xff0c;适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解&#xff0c;并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...