JVM (基础概念、类加载过程、垃圾回收算法)

news2024/12/23 15:56:26

目录

一、JVM 是什么

二、JVM 运行流程

三、Java运行时数据区

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

2、栈区(线程私有)

3、堆

4、方法区

四、OOM内存溢出和内存泄漏

1、OOM内存溢出

2、内存泄漏

五、类加载过程

1、加载

2、连接

3、初始化

4、双亲委派模型

六、垃圾回收(GC)

1、 如何判断对象是死亡对象

(1)引用计数法

(2)可达性分析法

2、垃圾回收算法

(1)标记-清除算法

(2)复制算法

(3)标记-整理算法

(4)分代算法


 

一、JVM 是什么

        JVM 是 Java虚拟机 。虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统。即 JVM 是一台被定制过的现实当中不存在的计算机。

JDK、JRE、JVM之间的关系:

JDK:

   Java开发工具包,提供给Java程序员使用,包含了JRE,同时还包含了编译器javac与自带的调试工具Jconsole、jstack等。

JRE:

   java运行时环境,包含了JVM,Java基础类库。是使用Java语言编程写程序运行的所需环境。

JVM:

   Java虚拟机,运行Java代码。

二、JVM 运行流程

        程序在执行之前先要把Java代码转换成字节码文件,JVM首先要把字节码文件通过一定的方式用 类加载器 把文件加载到内存中的 运行时数据区。而字节码文件是JVM的一套指令集规范,底层的系统是看不懂的,因此需要用特定的命令解析器 执行引擎 将字节码翻译成底层指令系统再交由CPU去执行,而这个过程中需要调用其他语言的接口 本地库接口 来实现整个程序的功能。

Java进程启动的大概步骤:

① 初始化JVM参数

② 创建并启动 java虚拟机

③ 启动 main 线程执行入口函数 —— 入口类类加载,再执行 main 方法

④ 启动守护线程:GC(垃圾回收机制)线程等 

三、Java运行时数据区

        Java运行时数据区域也叫内存布局,有五部分组成。

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

        程序计数器存的是CPU下一条要执行的指令的地址。比如1个CPU,但是有8个线程,它们并发执行(宏观上),可能第一个线程执行到第4行,第二个线程执行到第10行,第三个线程执行到第2行...

2、栈区(线程私有)

        栈中存放的是局部变量,以及方法调用时候的相关信息。

Object o = new Object();

o : 栈里

new Object():堆里

3、堆

        程序中创建的对象都保存在堆中。堆区主要有两个部分:新生代老年代。新生代放新创建的对象,当经过一定GC次数后还存活的对象就会放到老年代。

        新生代中还有两个部分:Endn两个Survivor(S0/S1)垃圾回收的时候,会将Endn中存活的对象放到一个未使用的Survivor中,并把当前的End和正在使用的Survivor清理掉。 

4、方法区

        用来存储被虚拟机加载的类信息常量静态变量、即时编译器编译后的代码等数据。

        在《Java虚拟机规范》中把此区域称为 方法区。而在实现中,JDK 7时叫做 永久代,JDK 8时叫做 元空间。(可以理解为方法区的实现,也可以理解为不同的方法区的称呼)

类信息(类对象)

        .class文件加载到内存里就是类对象,类对象中可以知道这个类里有哪些方法,有哪些静态成员,以及这些方法的权限:public、private等。

四、OOM内存溢出和内存泄漏

1、OOM内存溢出

        OOM内存溢出是指程序出现 “java.lang.OutOfMemoryError”。内存对象确实应该存活。此时要根据JVM参数与物理内存比较检查,看是否还应该把JVM内存调大、或者检查对象的生命周期是否过长了。

除了程序计数器以外的5个区域都有可能出现OOM内存溢出:

  • Java虚拟机栈、本地方法栈创建栈帧时,如果空间不足,则会OOM;
  • 方法区、堆在类加载、创建对象时,如果空间不足,先GC(垃圾回收),GC后还是空间不足的话,就会OOM。

2、内存泄漏

         指无用对象(不再使用的对象)持续占有着内存,或者无用对象的内存得不到及时的释放,从而造成内存空间的浪费。(泄漏对象无法被GC)

出现的情况:

随着Java程序运行的时间越来越长,无用对象越来越多,可用的空间越来越少;

java进程一直执行,内存泄漏最终导致OOM。

五、类加载过程

1、加载

        加载属于类加载的一个环节,主要是把.class文件加载到内存中。

JVM主要完成下面三件事:

  1. 根据类名,找到.class文件
  2. 把.class文件加载到内存
  3. 创建一个类对象

2、连接

(1)验证:验证.class文件是否符合JVM标准,是否会危害到虚拟机。

(2)准备:给静态变量赋0值。

(3)解析:初始化常量的过程。(Java虚拟机将常量池中的符号引用替换为直接引用的过程)

         常量池中,每个常量都有一个编号,最开始的时候,这个敞亮的引用,也就是a,对应的是这个常量的编号(符号引用),并不是“abcd”。这一步就是把编号替换成真是的值(“abcd”)。

3、初始化

        执行构造方法的过程。

注意:

public class Test extends B{
    public static void main(String[] args) {
        new Test();
        new Test();
    }

}
class A{
    public A(){
        System.out.println("A 的构造方法");//4
    }
    {
        System.out.println("A 的构造代码块");//3
    }
    static {
        System.out.println("A 的静态代码块");//1
    }
}
class B extends A{
    public B(){
        System.out.println("B 的构造方法");//6
    }
    {
        System.out.println("B 的构造代码块");//5
    }
    static {
        System.out.println("B 的静态代码块");//2
    }
}

打印结果:

4、双亲委派模型

        双亲委派模型是指,如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一层次的类加载器都是如此。因此所有加载请求最终都应该传送到最顶层的启动类中,只有当父加载器反馈回来说自己无法完成这个加载请求时(在它的搜索范围中没有找到所需的类),子加载器才会尝试自己完成加载。

启动类加载器:加载 JDK 中 lib 目录中的 Java 的核心类库。(JAVA_HOME/lib 目录)

扩展类加载器:加载 lib/ ext 目录下的类。

应用程序类加载器:加载我们写的应用程序。

自定义类加载器:根据自己的需求定制类加载器。

六、垃圾回收(GC)

        因为有一些对象在使用完之后就不使用了,就会变成垃圾,因此JVM会自己进行清理。JVM主要有程序计数器、堆、栈(虚拟机栈、本地方法栈)、方法区组成,而程序计数器和栈是线程私有的,会自动回收掉垃圾,因此主要在堆中进行垃圾回收。(堆是JVM中最大的一块内存空间)

GC中内存划分:

1、 如何判断对象是死亡对象

(1)引用计数法

        给对象增加一个引用计数器,每当有一个地方引用它是,计数器就+1,。当引用失效时,计数器就-1。当计数器为0时,就说明对象不再被使用了,即对象是死亡对象了。

优点:

        简单

缺点:

  • 会浪费一部分空间用来计数。(假如一个对象是2个字节,但是这个用来计数的空间是4个字节)
  • 不能解决循环引用的问题。即不能回收循环引动的对象。(在主流的JVM中没有使用该方法)

(2)可达性分析法

        通过一系列的被称为 “GC Roots” 的对象作为起始点,从这些结点开始向下搜索,搜索走过的路径称为 “引用链”。当一个对象到 GC Roots没有任何引用链时(即GC Roots到这个对象是不可达的),就说明这个对象是死亡对象。

可以作为 GC Roots 的对象包含以下几种:

  1. 虚拟机栈中引用的对象。(栈帧中的本地变量表中)
  2. 方法区中的类静态属性引用的对象。
  3. 方法区中常量引用的对象。
  4. 本地方法栈中JNI引用的对象。(Native方法)

2、垃圾回收算法

(1)标记-清除算法

        有两个阶段:标记清除。先标记出所有需要回收的对象,在完成标记后统一回收所有被标记的对象。(后面的算法都是基于标记-清除算法的改进)

回收的时候:

在新生代中,将 Endn 中存活的对象放到一个未使用的Survivor中,并把当前的 Endn 和正在使用的 Survivor 清除掉。

缺点:

  • 效率问题:标记和清除的过程效率都不高;
  • 空间问题:标记清除后会产生大量的不连续的内存碎片,可能会导致在以后层序的运行过程中,需要分配较大的对象时,无法找到足够连续的内存而不得不提前触发新的垃圾回收。

 

(2)复制算法

        为了解决 标记-清理 的效率问题。把一块内存划分为相同大小的两块,每次只使用其中一块(创建对象),回收时,把存活对象复制到另一块空置的内存中。

        用于存活对象较少的情况。

是新生代的回收算法。

使用场景:对象存活率低。

缺点:内存利用率低,50% 

 

(3)标记-整理算法

        标记过程和标记清除过程差不多,只是在标记完后,不立马进行清除,而是将存活对象都向一端移动,将存活对象移动到一端连续的空间,最后清理掉端外剩余的内存。      

是老年代的回收算法。

不会产生内存碎片,效率较高。

(4)分代算法

        是jvm采取的算法。把内存划分为许多块,针对不同的内存对象的创建、回收特性,使用不同的算法。(类似一国两制)

GC内存划分,不同的内存,使用不同的回收算法:

新生代使用复制算法的优化版;

老年代使用标记清除算法或者标记整理算法。

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

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

相关文章

PMP课堂模拟题目及解析(第14期)

131. 项目经理正在制定干系人参与计划,并识别到一位权力等级较高但在项目中兴趣较低的干系人,项目经理应该如何对待该干系人? A. 重点管理 B. 随时告知 C. 监督 D. 令其满意 132. 项目经理识别到项目干系人具有明显不同的需求和期望。…

不合格机器人工程专业讲师笔记-230529-

工作八年,最大的遗憾,就是对不起学生,对不起同事,对不起领导,各项工作都没有做好。 但是由于个人水平低,能力差,唯一能做的就是在忏悔中不断总结,避免一次又一次失败。 一万句&…

别让测试岗位的坑太大,10年老鸟亲身经历告诉你如何避开陷阱

测试岗位一直是IT行业中备受争议的一个职业,有人看重其重要性,有人则认为这是个巨坑。如果你也对测试岗位存在疑虑和担忧,那么这篇文章一定能帮到你! 作者是一位在测试领域摸爬滚打了10年的老鸟,他深刻地理解了测试工…

行业报告 | 智能制造在中国—中国机器视觉产业链现状分析

文 | BFT机器人 导语 Introduction 智能制造装备是指具有感知、分析、推理、决策、控制功能的制造装备,它是先进制造技术、信息技术和智能技术的集成和深度融合,体现了制造业智能化、数字化和网络化的发展要求。智能制造装备的水平已成为当今衡量一个国家…

数据类岗位面试随想录

数据分析或者是偏向数据分析的数据开发岗,要求无非就是SQL、Python和业务相关的问题。 1 SQL问答 基本这些问题和期末考试的难度比,是简单的。和学校所教的比,基本超纲的问题只会有窗口函数。这一部分面试官一般不会问你难的问题&#xff0c…

通用支付系统设计

支付永远是一个公司的核心领域,因为这是一个有交易属性公司的命脉。那么,支付系统到底长什么样,又是怎么运行交互的呢?抛开带有支付牌照的金融公司的支付架构,下述链路和系统组成基本上符合绝大多数支付场景。其实整体可以看成是…

【人脸识别】insightface 使用记录和搭建服务注意点 从0到1

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言1.开始1.1 前置1.2 再次运行,人脸检测跑通 前言 人脸识别项目,再走一遍。之前是公司老人留下的,没部署过,没交付…

【HMS Core】Health Kit关于获取历史数据问题

【问题描述1】 应用已经开通了历史数据访问权限,同时用户在授权页面已经勾选了”历史数据“项,然后我们是调用healthkit的rest接口查询健康数据,那么是否用户授权之前一年的健康数据都能被查询到呢? 【解决方案】 当用户授予应用…

5月底了,让我看看有多少准备跳槽的····

前两天跟朋友感慨,今年的铜三铁四、裁员导致好多人都没拿到offer!现在已经5月底了,具体金九银十只剩下3个月。 对于想跳槽的职场人来说,绝对要从现在开始做准备了。这时候,很多高薪技术岗、管理岗的缺口和市场需求也出来了。 所…

字节跳动测试岗,3面都过了,HR告诉我这个原因被刷了...

说在前面 面试时最好不要虚报工资。本来字节跳动是很想去的,几轮面试也通过了,最后没offer,自己只想到下面几个原因: 虚报工资,比实际高30%; 有更好的人选,这个可能性不大,我看还在…

6个月的测试,来面试居然要18K,我一问连8K都不值

2023年4月份我入职了深圳某家创业公司,刚入职还是很兴奋的,到公司一看我傻了,公司除了我一个自动化测试,公司的测试人员就只有2个开发3个前端1个测试还有2个UI,在粗略了解公司的业务后才发现是一个从零开始的项目&…

笔记本电脑正常开机但是桌面变成错误代码怎么办?

笔记本电脑正常开机但是桌面变成错误代码怎么办?有用户将自己的笔记本电脑开机之后,电脑可以正常开启,但是系统在加载的过程中,突然变成了一些错误代码,无法正常的到达桌面上。那么这个问题怎么去进行解决呢&#xff1…

操作系统学习系列(1.启航)-操作系统基本概念

文章目录 前言操作系统基本概述中断与硬件的基本交互基本地址地址概念启动流程应用程序与操作系统的关系 Hello World启动总结 前言 本系列博文主要用于第二阶段深入了解的408专业内容考研使用。也就是说在开启本系列之前,最好已经对408有基本的了解。重复的基础概…

推动网络安全的三大问题

网络攻击已成为技术主管和企业最关心的问题之一。预计到2025 年,网络犯罪将使公司每年损失 105 亿美元。2021 年网络犯罪的预估成本为 6.1 万亿美元,预计每年增长 15%。 企业正在增加网络安全预算以保护其资产。2022年,网络安全职位的发布数…

私域运营需要怎么样才能做好?

进入2023年,越来越多品牌商家意识到,“私域运营”已经成为品牌营销的必选项。作为私域运营的核心阵地,微信凭借社群、企业微信、小程序、视频号等多个生态插件,为品牌私域经营提供了很多创新思路,其中“社群微信管理”…

01.GATK肿瘤基因变异最佳实践SnakeMake流程:WorkFlow简介

<~生~信~交~流~与~合~作~请~关~注~公~众~号生信探索> 代码地址 https://jihulab.com/BioQuest/smkhsshttps://github.com/BioQuestX/smkhss GATK best practices workflow Pipeline summary SnakeMake workflow for Human Somatic short variants (SNPINDEL) Expected fa…

JAVA开发(小程序商城价值画像)

小程序商城是一种流行的电子商务形式&#xff0c;允许用户通过微信或其他应用程序直接购买商品。随着消费者对在线购物的需求和期望不断增加&#xff0c;小程序商城已经成为一个不可或缺的销售渠道。本文将探讨小程序商城的价值画像&#xff0c;包括其优点、挑战和未来发展趋势…

接口测试|Fiddler弱网测试

Fiddler进行弱网测试 弱网测试 概念&#xff1a;弱网看字面意思就是网络比较弱&#xff0c;我们通称为信号差&#xff0c;网速慢。 意义&#xff1a;模拟在地铁、隧道、电梯和车库等场景下使用APP &#xff0c;网络会出现延时、中断和超时等情况。 在这里插入图片描述 Fidd…

子域名接管劫持

什么是域名劫持&#xff1f; 域名劫持也被称为DNS劫持&#xff0c;它通过攻击域名解析服务器、伪造域名解析服务器的方法&#xff0c;拦截目标的域名解析请求&#xff0c;将目标网站域名解析到错误的地址上&#xff0c;让攻击目前无法回应访问。 子域名接管漏洞通常被滥用于以…

大数据简介

大数据简介 什么是大数据 ​ 最近几年&#xff0c;IT行业最火的名词中&#xff0c;少不了"大数据"、"人工智能"、"云计算"、"物联网"、"区块链"等等这些名词。针对于"大数据"这个名词&#xff0c;现在更是全国老…