八股文之JVM

目录

1.JVM内存划分

2.JVM类加载过程

3.JVM垃圾回收机制GC

3.1.判断谁是垃圾

3.2.如何释放对应的内存


1.JVM内存划分

在一个Java程序运行起来之后,jvm就会从操作系统中申请一块内存,然后就会将该内存划分成多个部分,用于不同的用途。

(1)主要划分成五个部分

堆、栈、元数据区(方法区)、常数计数器(很少涉及)

图示:

像堆区中的各个部分划分,在后面的垃圾回收机制再拿出来鞭策一遍,在这里就不先做任何的赘述。

(2)每块内存区的功能

堆区:

整个内存区域中最大的区域,用于存放java代码中new出来的对象、和成员变量。

栈:

一般java是使用jvm虚拟机栈,这里保存了方法的调用关系、局部变量等。也就是每个方法怎么被调用,被谁调用等

元数据区:

元数据区,以前也成为方法区,用来存放类对象、类属性(静态成员)、常量

程序计数器:

属于内存中最小的区域,用来保存要执行的下一条指令的地址

(3)实战划分内存

看下嘛的一段代码,查看下面的变量和对象分别处于哪一块内存中

class Demo2 {}
class Demo1 {public int a;Demo2 b = new Demo2();public String c = "love";public static int d;}public class Test {public static void main(String[] args) {Demo1 e = new Demo1();}
}

对于变量:a,b,c,d,e 其中a,b,c都属于成员变量,存在于堆上;而e属于局部遍历,存在栈上;而d属于静态成员变量,属于类属性,存在于元数据区。它们只是属于变量,里面存有一个值,会指向另一块内存空间。

各对象内存分布和指向关系

以上就是对应的各种关系。

对于上述的四个区域,堆和元数据区,在整个进程中只有一份,而栈和程序计数器,是每个线程都有一份。

2.JVM类加载过程

一个.java文件变成.class文件的过程,也是从硬盘加载到内存中,得到类对象的过程。

(1)类加载的五个环节

加载、验证、准备、解析、初始化

(2)每个环节对应的作用

1.加载

在硬盘上找到对应的.class文件,并且读取.class文件内容

2.验证

检查.class文件中的内容,是否符合要求(如文件格式等)

3.准备

给类对象分配内存空间

4.解析

对字符串常量初始化,把刚才.class文件中的常量内容取出来放到元数据区

5.初始化

针对类对象进行初始化,给静态成员初始化,也就是执行静态代码块

(3)“双亲委派模型”

在第一步的加载环节,目的是打开.class文件,前提就是需要通过“全限定类名”找到文件才能进行打开,所以“双亲委派模型”就是寻找.class文件的一种机制。

在这个环节,涉及到一个概念:类加载器

在JVM中也会包含一些类,负责完成后续的类加载工作。其中JVM内置了三个类加载器,负责加载不同的类

分别是三个类:BootstrapClassLoader、ExtentionClassLoader、ApplicationClassLoader

1)三个类加载器作用

所以成为双亲委派模型,但是跟准确的说法为:父亲委派模型或者单亲委派模型

2)加载过程

那么双亲委派模型是如何找类的呢?我们举一个例子,假设我们自己写了一个java程序,会给定一个全限定类名

3)双亲委派模型应对的场景

如果自己的代码中写的类的名字和标准库/扩展库冲突了,JVM会确保加载的类是标准库的类(不会加载自己写的类),如果标准库中的类无法加载,那么Java进行就没有办法正常工作了。

这样还有一个好处,就是可以确保自己写的类肯定可以被加载到。

3.JVM垃圾回收机制GC

对于Java,回收垃圾采取的是自动回收策略,策略也称为GC。

对于GC来说,回收的其实是堆上的内存。而对于堆,保存的主要是对象,换句话说,也就是主要回收对象,那怎么回收对象呢?主要有两个步骤:判断谁是垃圾和如何释放其对应的内存。

3.1.判断谁是垃圾

在判断谁是垃圾这一步,Java是采取很保守的做法,也就是可以保证只会释放后续不会再使用的对象,后续仍会使用到的对象,是不会进行回收的,所以才用的策略是:判断某个对象是否存在引用指向,如果没有引用指向,就可以判断为垃圾,反之不行。

判断谁是垃圾,GC有两种策略:引用技术和可达性分析,而JVM采取的策略只有可达性分析,引用计数则不是。

(1)引用计数

1)策略:每创建一个对象,就在对象前面多开辟一块空间,用来计数使用,有一个引用指向该对象,计数变量就+1,如果计数器为0,则需要回收该对象。

2)代码举例

class TT {}
public class GC {public static void main(String[] args) {TT a = new TT();TT b = a;}
}

对于实例化的TT对象,当前有两个对象指向它,所以计数值为2(分别是引用a和b),如果a=null或者b=null,则计数值-1,两个都置为null,则计数为0.

对于引用计数存在两个问题

问题一:会消耗额外的内存空间

如果对象本身的内存比较大,相比来说计数的空间就很小;但是如果对象内存空间很小,那么计数空间就会显得很大,就会浪费很大的空间

问题二:存在“循环引用”问题

这类问题就会让外部代码无法对 对象进行释放

代码举例:

class T {T t;
}
public class GC {public static void main(String[] args) {T a = new T();T b = new T();a.t = b;b.t = a;}
}

这是一段有问题的代码

图示分析:

存在的问题:当将引用a和b置为null时,按理来说这两个对象是要被回收了,但是这里却不会,因为计数不为0,不能回收。所以这就是引用计数最大的一个问题。

(2)可达性分析

JVM采取的是可达性分析,既解决了空间问题,也解决了循环引用问题。

1)定义:JVM会把对象之间的引用关系,定义成树形结构,JVM可以不停的从根节点开始遍历,可以访问到的对象,成为“可达”,剩下的就是“不可达”。

标记为不可达的对象,也就被标记成垃圾。

2)举例

例如这样的结构,如果将c=null,那么c后面的两个对象f和g就变成不可达,就要成为垃圾。

访问这棵树的所有节点,都是要通过根节点a开始。

3)确定根节点

对于根节点,可能的情况有:栈上的引用局部变量、常量池中引用的对象、方法区中的静态成员。

3.2.如何释放对应的内存

当已经标记好垃圾之后,该怎么回收呢?下面介绍。一共四种,前面三种是铺垫,最后一种才是JVM真正使用的

(1)标记-清除

策略:直接把标记为垃圾对象的对应的内存回收,已经回收的内存,其他对象可以使用

缺点:这样做很存在内存碎片问题,后续就很难申请到一大块连续的空间

(2)复制算法

策略:要删除空间1中abcd中的ac,就直接将bd复制到另一块空间中

缺点:严重浪费空间。比如有8G内存,就只能使用4G

(3)标记-整理

策略:把不需要释放的内存空间覆盖到需要释放的空间上。可以解决内存碎片问题

缺点:时间开销很大

(4)分代回收

策略:根据不同的场景,采取不同的回收策略,这里的回收策略也就是上述介绍到的。

如何根据场景呢?就是要根据时间来,哪个时间呢?就是对象的年龄。

因为GC主要回收的地方就是堆区,所以堆区上会有对应的分区,不同的区代表对象的年龄

Eden:称为伊甸区,新创建的对象都处于这里。

这里的对象生命周期都很短,一般经过一轮GC就会成为垃圾。从伊甸区到达生存区,采取的是复制算法

s0:称为生存区,一般经过一轮还未被回收,就会到达下一个阶段

从生存区到达幸存区,也是通过复制算法

s1:称为幸存区

这里也称为生存区,到达这里也需要通过复制算法。

Old区:到达这里的对象都会成为老年代的对象,GC的扫描频率会大幅度降低。

对于老年代中的垃圾,就会通过标记-整理的方法进行回收

总结一下:伊甸区、生存区、幸存区都是通过复制算法回收垃圾很搬运到下一个区,对于老年区,则是通过标记-整理回收垃圾。

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

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

相关文章

目标与学习方向

文章目录 一、任务最终目的二、所需技术栈1、前端开发2、后端开发3、数据库管理 三、WEB全栈开发路线1、学习HTML、CSS、JavaScript2、了解版本控制3、学习前端框架4、学习服务器端编程5、数据库6、构建RESTful API7、深入学习后端框架8、了解网络安全9、熟悉DevOps10、其他技能…

一、开发环境安装 Avalonia

1、概述 官网中是这么介绍Avalonia的,Avalonia是一个强大的框架,使开发人员能够使用.NET创建跨平台应用程序。它使用自己的渲染引擎绘制UI控件,确保在Windows、macOS、Linux、Android、iOS和WebAssembly等不同平台上具有一致的外观和行为。这…

WebSocket进行握手需要的字段

一、客户端请求必须要有的头: Upgrade: websocket Connection: Upgrade Sec-Websocket-Key: 随机生成的字符串 Sec-WebSocket-Protocol: chat Sec-WebSocket-Vesion: 13 二、服务端响应必须要有的头: Upgrade: websocket Connection: Upgrade SecWebSock…

CCAA认证人员注册全国统一考试开始报名

备受瞩目的CCAA(中国认证认可协会)认证人员注册全国统一考试即将拉开报名序幕。 考试基本信息: 1)报名网站网址:https://kaoshi.ccaa.org.cn/ 2)考试报名系统自2024年6月17日12:00时起面向考生正式开通&…

c++编程(19)——STL(5)容器适配器

欢迎来到博主的专栏——c编程 博主ID:代码小豪 文章目录 适配器adaptorstackqueuepriority_queue传送门: 适配器adaptor 适配器看起来像一个容器,实际上adaptor并不属于容器的范畴,更像是一种专门用于某种容器的接口。 常用的适…

关于渗透测试

目录 1渗透测试的目的 2渗透测试的手段 3渗透测试发现的问题分类 1渗透测试的目的 检验目的系统的安全性 2渗透测试的手段 1智能工具探测 2人工测试 3分析 3渗透测试发现的问题分类 SQL注入-高风险 垂直越权-高风险 链接注入-高风险 源码泄露-中风险 短信验证码重复利用-中风…

智能不锈钢氮气柜温湿度氧含量控制介绍

智能不锈钢氮气柜通过集成精密的温湿度和氧含量控制系统,确保内部环境稳定在适宜存储敏感物料的条件。具体实现方式如下: 温度控制:智能氮气柜通常配备有精确的温度传感器以及加热或冷却系统。当内部温度偏离设定值时,系统会自动启…

0617_QT3

练习: #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//去掉头部this->setWindowFlag(Qt::FramelessWindowHint);//去掉空白部分this->setA…

Misc之图片隐写

前几天忙高数和c考试去了。。。Web毫无进展,学学这个放松一下 一、工具准备 这里目前使用的工具为kali上的工具和安装在电脑上的Winhex,010editor,Stegsolve 二、png图片隐写 这里我就直接用题目学习了,也是参考了csdn上大佬的…

C语言socket TCP/IP通讯Server/Client程序(Ubuntu Linux 24.04环境)

继上篇文章介绍了Ubuntu Linux 24.04 C语言TCP/IP socket编程基础知识,本文将用C语言在Ubuntu Linux 24.04环境下开发一对使用socket进行TCP/IP通讯的Server/Client程序,实现的功能是: 1. 当client连上server时,显示连接成功的信…

MYSQL 数字(Aggregate)函数

目录 1、AVG() 2、MAX() 3、MIN() 4、SUM() 5、COUNT() 6、LIMIT() 1、AVG() 解释:返回数值列(字段)的平均值。 语法格式:SELECT AVG(column_name) FROM table_name 中文注释:select AVG(数值列/字段) from 表名 ; 用法&#xff1…

一五三、MAC 安装MongoDB可视化工具连接

若没有安装brew包管理工具,在命令行输入安装命令 /bin/bash -c “$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)”上面步骤安装完成后,开始安装MongoDB,输入安装命令: brew tap mongodb/brewbrew u…

【前端】Nesj 学习笔记

1、前置知识 1.1 装饰器 装饰器的类型 declare type ClassDecorator <TFunction extends Function>(target: TFunction) > TFunction | void; declare type PropertyDecorator (target: Object, propertyKey: string | symbol) > void; declare type MethodDe…

GenICam标准(三)

系列文章目录 GenICam标准&#xff08;一&#xff09; GenICam标准&#xff08;二&#xff09; GenICam标准&#xff08;三&#xff09; GenICam标准&#xff08;四&#xff09; GenICam标准&#xff08;五&#xff09; GenICam标准&#xff08;六&#xff09; 文章目录 系列文…

黑马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录Day3 全网最全

你好,我是Qiuner. 为帮助别人少走弯路和记录自己编程学习过程而写博客 这是我的 github https://github.com/Qiuner ⭐️ gitee https://gitee.com/Qiuner &#x1f339; 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 &#x1f604; (^ ~ ^) 想看更多 那就点个关注吧 我会…

Spark大数据处理技术(期末复习)

Spark大数据处理技术&#xff08;期末复习&#xff09; 1)var a:Double5;var b:Int7;那么print(a*b) 35.0 2) var a:Int5; var bif(a>6) 7 println(b) 不满足 &#xff08;&#xff09; 3)var a:Int16; var b:Int13; var cif(a>b) 5 else 7; println(c) 5 4. object …

查看 RK3568 Android SDK 版本的详细指南

目录 前提条件方法一&#xff1a;通过getprop命令查看系统属性方法二&#xff1a;通过build.prop文件查看版本信息方法三&#xff1a;查看源码中的配置文件方法四&#xff1a;通过编译输出查看版本信息附录&#xff1a;常见问题及解决方法1. adb 命令找不到设备2. getprop 或 c…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] K小姐和A先生的聚餐计划(200分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; &#x1f…

SQL优化选对执行计划,查询速度提升1000倍 | OceanBase 应用实践

作者&#xff1a;爱可生数据库高级工程师任仲禹&#xff0c;擅长故障分析和性能优化。 本文通过一个案例&#xff0c;分享使用OceanBase时&#xff0c;SQL走错执行计划&#xff0c;而导致慢SQL的排查方法论。 案例背景 在使用OceanBase 3.2.3 版本的过程中&#xff0c;项目组反…

Java——IO流(字符流,字节流)

JavaIO的整体框架图 IO流从方向上来说&#xff0c;可以分为输入流和输出流&#xff1b; 从传输内容上来说&#xff0c;可以分为字符流和字节流 防止记混的口诀 所谓的IO&#xff0c;说白了就是数据在内存和硬盘之间的传输 输入流 %Reader %InputStream&#xff0c;从硬盘写…