java 核心知识点——JVM

embedded/2024/12/25 13:55:54/

目录

什么是Java虚拟机?

虚拟机架构设计

为什么用元空间取代永久代

双亲委派机制

分代年龄为什么是15次

GC算法

如何判断一个对象可以被回收


什么是Java虚拟机?

Java virtual machine。虚拟机,像真实的计算机一样,能够运行字节码指令。好处是屏蔽了操作系统的细节,使用Java可以一处编写,到处运行。

虚拟机架构设计

类加载子系统:将编译好的class文件加载到类加载子系统里,功能是查找并验证类文件,完成相关的内存分配和对象赋值。
运行时数据区:完成数据存储和数据交换。分为线程共享和隔离区。线程共享区包括方法区和堆区,他们程序员能够通过编写代码直接操作的内存区,隔离区包括:栈,程序计数器,本地方法栈,他们是由jvm调度的内存区。
方法区:主要功能是存储运行时常量池,字段,方法元数据和类的元数据。
堆:存储Java对象的实例,新建的类的实例都存在堆区。
栈:通过线程的方式运行来加载各种方法。
程序计算器:保存了每个线程执行方法的地址。
本地方法区:加载并运行native方法。
运行时数据区的5个内存区就能完成Java程序的逻辑执行和数据的交换。
执行引擎:即时编辑器:将字节码翻译成操作系统能够执行的CPU指令,可以通过jvm参数来设置解释执行或者编译执行。解释执行就是直接将字节码作为源程序输入执行,不必等待编译全部完成再执行,可以省去不必要的编译时间。编译执行就是由编译程序将目的代码一次性编译成目标程序,再由机器执行,执行效率更高,占用内存资源更少。
垃圾回收器:负责对运行时数据区的数据进行管理和回收,3中回收算法:复制,标记清除,标记整理。我们可以通过jvm参数设置使用哪种算法。
本地方法接口,jni,可以通过JNI查找和加载C或C++代码,操作系统的动态链接库DLL

为什么用元空间取代永久代

jdk1.8hotspot取消了永久代使用元空间实现方法区存储数据。元空间使用本地内存,不用考虑GC问题。在默认情况下元空间可以无限制使用本地内存,可以限制大小。
取代原因:1.永久代内存是有上限的,虽然可以设置大小,但是jvm加载class总数,大小是很难确定的,所以任意出现OOM问题,元空间使用本地内存,上限比较大,可以避免这个问题。
2.永久代通过full GC进行垃圾回收,也就是和老年代同时实现垃圾回收。永久代被元空间替换后,简化FULL GC。可以在不暂停的情况下释放数据,同时也提高了GC性能。

双亲委派机制

类加载机制:Java编译器将Java源文件编译成class文件,再由JVM类加载器加载class文件到内存,jvm加载完成后得到一个class对象。拿到类对象之后就可以进行实例化。
类加载器:jvm设计3个类加载器加载不同范围的jar包和class文件。
核心类库加载器bootstrap,加载Java的核心类库,Java_home\lib目录下的rt.jar,resources.jar
扩展类加载器extension,Java_home\lib\ext目录下jar,classapplication,当前应用中的classpath下的jar,class
自定义类加载器,classLoader类实现
双亲委派机制是按照类加载器的层级关系逐层进行委派。例如,我们需要加载一个class文件的时候,首先把这个class文件的查询和加载交给父加载器执行,如果父加载器不能加载,在自己加载这个class文件。
有2个好处:1保证安全性,因为这种层级关系代表一种优先级,所有类的加载优先使用bootstrap.那么对于核心类库中的类就不能破坏,比如自己写一个string,最终还是会交给bootstrap类加载器加载。在加上每个类加载器有不同的作用范围,就意味着自己写的string不能覆盖核心类库中的类。2.避免重复加载,如果已经加载过来就没有必要再次加载。

分代年龄为什么是15次

堆内存分为young generation(Eden space,survivor space),old generation。使用new创建对象的时候,jvm会在Eden space 分配一块内存来存储这个对象。Eden space内存不足时会触发young GC进行对象回收,存在引用关系的对象,jvm把他们移动到survivor space。
survivor space 分为from 和 to 区,刚从Eden space 转移过来的对象被分配到 from区,每经历一次youngGC这些没有别回收的对象在from和to区来回移动,每移动一次,对象的GC年龄加1.默认情况下当分代年龄到达15时候,jvm就移动对象到old generation。
对象的GC年龄存储在对象头里,一个对象在jvm内存里由3个部分组成,对象头,实例数据,对齐填充。对象头有4位存储GC年龄,4位存储最大数15.jvm提供参数设置GC年龄大小,不能超过15,若一个对象触发了15GC还没有回收,就移动到老年代。动态年龄判断方法决定是否移动到老年代。

GC算法

标记清除:将存活对象打上标记,没有标记的对象就是垃圾对象需要被垃圾回收器回收。缺点:产生较多的内存碎片,随着时间推移,这些碎片使得系统无法再大量分配连续的内存空间。导致频繁触发GC操作。
标记复制:把内分为2等分,每次只使用其中一份,等待这部分使用的内存满了之后,标记存活对象,然后把存活对象复制到另一部分闲置的内存里,留在第一部分内存里的对象全部回收。那么空闲下来的内存空间成为了使用状态,而原来使用中的内存空间闲置下来继续使用。之后重复这个循环。缺点:我们实际使用的内存空间只有50%,而另外一半空闲的。浪费内存空间。如果大量复制对象,垃圾回收耗时就比较长,适用于存活对象少垃圾对象多的情况。
标记整理:标记出存活的对象,再把所有存活对象整理到内存空间的另一端,而没有被标记的对象可以被覆盖或者释放。缺点:和标记清除算法差不多,只不过增加了把存活对象移动到一起的操作。
Java对象基本是临时对象,很快被回收,jvm使用了分代设计,根据对象在内存里的存活时间,分为年轻代,老年代和永久代。年轻代使用标记复制算法,每次复制的时候存活下来的对象较少。老年代是经历过几次垃圾回收的对象,jvm认为他们可以继续存活下去,采用标记清除算法。永久代表示一直会存活的对象,只有触发fullGC时候才会被回收。所以永久代创建对象过多容易内存溢出。

如何判断一个对象可以被回收

最重要的是判断这个对象是否还在被使用,只有没有被使用的对象才能被回收。
引用计算器:给每个对象添加一个引用计数器,记录指向当前对象的引用次数,一旦引用次数变成0,就可以回收了。
可达性分析:首先确定一系列肯定不能回收的对象,作为GC ROOT对象,例如,虚拟机栈引用的对象,本地方法栈引用的对象,然后以GC ROOT对象作为起始点向下搜索,寻找他的直接和间接引用对象。在遍历完成后,发现有一些对象不可达,这样的对象可以被回收。这个过程需要暂停所有用户线程。


http://www.ppmy.cn/embedded/148635.html

相关文章

thinkphp6使用MongoDB多个数据,聚合查询的坑

我使用的是thinkphp6,mongodb4.0实际业务查询 $list Db::connect(tstd_mongo)->table("$table_time.Item")->where($where)->order("Cause","asc")->field(_id,DBID,Data,GSID,MainKind,ManID,DISTINCT(Serial) Serial,SubKind,Tim…

VisionPro开发使用交互反馈系统(Affordance System)

XR Interaction Toolkit 提供了一个affordance system 可供性系统,使用户能够创建对交互状态的视觉和听觉反馈。一般的信息流从向Affordance State Provider场景中添加一个(通常是可交互的)并将其指向我们要监视其交互状态的可交互对象开始。…

docker部署微信小程序自动构建发布和更新

通过 Jenkins 和 Docker 部署微信小程序,并实现自动构建、发布和版本更新,主要涉及以下几个步骤: 设置 Jenkins 环境配置 GitLab 与 Jenkins 的集成构建 Docker 镜像部署和发布微信小程序配置 Jenkins 自动构建 以下是详细的步骤说明&#…

embeding 层到底是什么

embending 的本质是 word2vec 大白话讲解word2vec到底在做些什么 那时候 博主还比较年轻 ,啃过托马斯马尔科夫的 word2vec 源码 ,那是一个三层神经网络,用C实现的 ,最近创业失败了 ,又去找工作,啥都不会,被…

小红书关键词搜索采集 | AI改写 | 无水印下载 | 多维表格 | 采集同步飞书

小红书关键词搜索采集 | AI改写 | 无水印下载 | 多维表格 | 采集同步飞书 一、下载影刀: https://www.winrobot360.com/share/activity?inviteUserUuid595634970300317698 二、加入应用市场 https://www.yingdao.com/share/accede/?inviteKeyb2d3f22a-fd6c-4a…

w113健身房管理系统

🙊作者简介:多年一线开发工作经验,原创团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹赠送计算机毕业设计600个选题excel文…

Python基础学习的资料

一、Python简介 Python是一种高级、解释型、通用的编程语言。它由Guido van Rossum于1989年开始开发,第一个公开发行版发行于1991年。 特点 简洁易读 Python代码简洁明了,采用缩进的方式来表示代码块,而不是像其他语言使用大括号。例如&…

一文掌握如何编写可重复执行的SQL

一文掌握如何编写可重复执行的SQL 文章已同步个人博客:一文掌握如何编写可重复执行的SQL 背景 先提出问题,这里的可重复执行是指什么?我们为什么要编写可重复执行的sql? 可重复执行是指一条sql重复多次执行都不会报错&#xf…