JVM及垃圾回收算法

一、JVM

1、jvm的内存组成

五大内存区域,分1.7和1.8

1.堆内存:引用类型的数据,内部组成:1.新生代(伊甸区和幸存者区)2.老年代。该区域经常发生垃圾回收的操作

堆是JVM中最大的一块内存区域,用于存储对象实例和数组。堆被 所有线程 共享,用于 动态分配 内存。堆被分为新生代(Young Generation)和老年代(Old Generation)两部分,新生代又被分为Eden空间和两个Survivor空间。

2.虚拟机栈:方法在运行时,需要存储一些内容,存储到栈

虚拟机栈用于 存储方法的 局部变量、操作数栈、方法调用 和 返回等信息。每个线程在运行时都会有一个对应的 虚拟机栈,每个方法在执行时 都会 创建一个 栈帧(Stack Frame)。

3.本地方法栈:本地方法(被native修饰的方法),方法运行时,保存的一些信息

4.程序计数器:针对线程的,记录每个线程当前的执行的行数 每个线程都有一个独立的程序计数器。

5.元空间(1.7叫做方法区):存放已被加载的类信息、常量、静态变量等信息.

JDK 1.8 同 JDK 1.7 比,最大的差别就是:元数据区 取代了 永久代。元空间的 本质 和永久代类

似,都是对 JVM 规范中方法区的实现。不过元空间与永久代之间最大的 区别 在于:

元数据空间 并 不在 虚拟机 内存 中,而是 使用 本地内存

2、JVM的堆内存

堆内存:分为两块:1.新生代 2.老年代

新生代:内部又分为 伊甸园区 和 幸存者区 伊甸园区:幸存者区:幸存者区 = 8:1:1

创建新对象,默认进入到伊甸区,GC在运行时,会将存活的对象放在幸存者区,如果对象存活超过15次,存储到老年代

老年代:存活时间长的对象或者大对象

新生代、老年代 所占 比例 2:1

3、jvm内存模型

Java 内存模型(下文简称 JMM)就是在底层处理器内存模型的基础上,定义自己的多线程语义。它明确指定了一组排序规则,来保证线程间的可见性。

这一组规则被称为 Happens-Before, JMM 规定,要想保证 B 操作能够看到 A 操作的结果(无论它们是否在同一个线程),那么 A 和 B 之间必须满足 Happens-Before 关系

  • 单线程规则:一个线程中的每个动作都 happens-before 该线程中后续的每个动作

  • 监视器锁定规则:监听器的解锁动作 happens-before 后续对这个监听器的锁定动作

  • volatile 变量规则:对 volatile 字段的写入动作 happens-before 后续对这个字段的每个读取动作

  • 线程 start 规则:线程 start() 方法的执行 happens-before 一个启动线程内的任意动作

  • 线程 join 规则:一个线程内的所有动作 happens-before 任意其他线程在该线程 join() 成功返回之前

  • 传递性:如果 A happens-before B, 且 B happens-before C, 那么 A happens-before C

Java 提供了几种语言结构,包括 volatile, finalsynchronized, 它们旨在帮助程序员向编译器描述程序的并发要求,其中:

  • volatile - 保证可见性有序性

  • synchronized - 保证可见性有序性; 通过管程(Monitor)保证一组动作的原子性

  • final - 通过禁止在构造函数初始化给 final 字段赋值这两个动作的重排序,保证可见性(如果 this 引用逃逸就不好说可见性了)

编译器在遇到这些关键字时,会插入相应的内存屏障,保证语义的正确性。

有一点需要注意的是,synchronized 不保证同步块内的代码禁止重排序,因为它通过锁保证同一时刻只有一个线程访问同步块(或临界区),也就是说同步块的代码只需满足 as-if-serial 语义 - 只要单线程的执行结果不改变,可以进行重排序。

所以说,Java 内存模型描述的是多线程对共享内存修改后彼此之间的可见性,另外,还确保正确同步的 Java 代码可以在不同体系结构的处理器上正确运行。

二、什么是STW

STW: Stop-The-World: 是在垃圾回收算法执⾏过程当中,将JVM内存冻结、应用程序停顿的⼀种状态。

  • 在STW 状态下,JAVA的所有线程都是停⽌执⾏的 -> GC线程除外

  • 一旦Stop-the-world发生,除了GC所需的线程外,其他线程都将停止工作,中断了的线程直到GC任务结束才继续它们的任务

  • STW是不可避免的,垃圾回收算法执⾏一定会出现STW,我们要做的只是减少停顿的时间

  • GC各种算法优化的重点,就是 减少STW(暂停) ,同时这也是JVM调优的重点

三、垃圾回收的相关算法:

1、GC常用算法

标记清除算法

第一步:利用可达性去遍历内存,把存活对象、需要回收的对象标记出来;第二步:在遍历一遍,把标记过的对象回收掉。缺点:效率不高,无法清除垃圾碎片

标记整理算法

首先,把存活对象和垃圾对象进行标记,然后将所有的存活对象向一端进行移动,然后直接清除端以外的内存。特点:适用于存活对象多,垃圾少的情况;需要整理的过程,无空间碎片产生;

标记复制算法

按照容量复制两个大小相等的内存空间,当有一个用完以后,就把还存活着对象复制到另一个区域中,在清除掉用完的区域,缺点:内存使用率低,只有原来的一半空间

分代收集算法

根据内存对象的存活周期不同,将内存划分成几块,一般为新生代、老年代。

新生代一般采用复制算法,老年代一般采用标记整理算法。

2、GC如何判定对象是否回收

引用计数法

使用可达性分析算法来判定:GC Roots

3、如何判断一个对象是否存活?( 判断一个对象是不是垃圾 )

判断一个对象是否存活,分为两种算法1:引用计数法;2:可达性分析算法;

引用计数法: 给每一个 对象设置 一个引用计数器,当有一个地方 引用该对象 的时候,引用计数器就+1,引用失效时,引用计数器就-1;当引用计数器为0的时候,就说明这个对象没有被引用,也就是垃圾对象,等待回收; ​ 缺点:无法解决 循环引用 的问题,当A引用B,B也引用A的时候,此时AB对象的引用都不为0,此时也就无法垃圾回收,所以一般主流虚拟机都不采用这个方法;

可达性分析法 从一个被称为 GC Roots的对象向下搜索 ,如果一个对象到GC Roots 没有任何 引用链 相连接时,说明此对象不可用,在java中可以作为GC Roots的对象有以下几种:

  • 虚拟机栈 中引用的对象

  • 方法区 类静态属性 引用的变量

  • 方法区 常量池 引用的对象

  • 本地方法 栈 JNI 引用的对象

但一个对象满足上述条件的时候,不会马上被回收,还需要进行 两次标记; 第一次标记:判断当前对象是否有 finalize()方法 并且 该方法 没有被执行过,若 不存在标记为垃圾对象,等待回收;若的话,则进行 第二次标记; 第二次标记将当前对象放入 F-Queue队列,并生成一个finalize线程去执行该方法,虚拟机不保证该方法一定会被执行,这是因为如果线程执行缓慢或进入了死锁,会导致回收系统的崩溃;如果 执行了finalize方法之后仍然没有与GC Roots有直接或者间接的引用,则该对象会被回收;

4、被引用的对象就一定能存活吗?

不一定,看 Reference 类型,弱引用在 GC 时会被回收,软引用在内存不足的时候,即 OOM 前会被回收,但如果没有在 Reference Chain 中的对象就一定会被回收

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

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

相关文章

【爬虫】requests.post请求中的data和json使用区别

请求体是键值对形式(无花括号),请求时需要使用data参数处理。 代码: data {...} ret requests.post(url, headersheaders, datadata)请求体是字典形式(有花括号),请求时需要使用json参数处理。…

派对游戏2024年新局面:二超多强,市场细分

2023年末,《元梦之星》上线迎战《蛋仔派对》,网腾大战打响。 这场战役从开局就进入到了白热化,双方投入真金白银来拉拢玩家,于春节这一亲朋相聚最适合派对游戏的时段集中发力,互有胜负。 目前《元梦之星》略处下风&a…

Principled Instructions Are All You Need for Questioning LLaMA-1/2, GPT-3.5/4

Principled Instructions Are All You Need for Questioning LLaMA-1/2, GPT-3.5/4 相关链接:arxiv 关键字:Questioning LLaMA、GPT-3.5/4、guiding principles、prompting、large language models 摘要 本文介绍了26个旨在简化查询和提示大型语言模型&…

自然语言处理NLP:tf-idf原理、参数及实战

大家好,tf-idf作为文体特征提取的常用统计方法之一,适合用于文本分类任务,本文将从原理、参数详解和实际处理方面介绍tf-idf,助力tf-idf用于文本数据分类。 1.tf-idf原理 tf 表示词频,即某单词在某文本中的出现次数与…

力扣 322 零钱兑换

题目描述 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。 你可以认为每种硬币的数量是无限的。 示例 1: 输入:coins [1, 2, 5…

x6.js 从流程图组件库中拖拽组件到画布dnd使用

上一篇已经了解到了x6.js常用功能以及使用方法。但我们使用流程图的时候还少不了一个非常重要的功能那就是拖拽组件库里的组件进来。如下图: 首先是布局这块,拖拽组件库的视图中布局无需我们去写,我们只需把界面搭建好。 添加组件库 1.搭建布…

Python 基于 OpenCV 视觉图像处理实战 之 图像相关的基本概念,以及图像的基础操作 二

Python 基于 OpenCV 视觉图像处理实战 之 图像相关的基本概念,以及图像的基础操作 二 目录 Python 基于 OpenCV 视觉图像处理实战 之 图像相关的基本概念,以及图像的基础操作 二 一、简单介绍 二、图像的几何变换 三、插值算法 1、最近邻插值算法 …

java kafka客户端何时设置的kafka消费者默认值

kafka为什么有些属性没有配置却能正常工作,那是因为kafka-clients对有些消费者设置了默认值,具体看下ConsumerConfig类的静态模块,具体如下所示: kafka为什么有些属性没有配置却能正常工作,那是因为kafka-clients对有…

AJAX 02 案例、Bootstrap框架

AJAX 学习 AJAX 2 综合案例黑马 API01 图书管理Bootstrap 官网Bootstrap 弹框图书管理-渲染列表图书管理-添加图书图书管理-删除图书图书管理 - 编辑图书 02 图片上传03 更换图片04 个人信息设置信息渲染头像修改补充知识点:label扩大表单的范围 AJAX 2 综合案例 黑…

【FPGA】DDR3学习笔记(二)丨从SDRAM到DDR3的IP核设计

本篇文章包含的内容 一、DDR SDRAM1.1 基本概述1.2 工作时序(以读取为例) 二、DDR2 SDRAM2.1 基本概述2.2 工作时序 三、DDR3 SDRAM3.1 基本概述3.2 硬件设计3.3 读写时序3.4 MIG IP核设计3.5 读写代码设计 开发板:正点原子的达芬奇开发板&am…

【Leetcode每日一题】 递归 - 合并两个有序链表(难度⭐)(35)

1. 题目解析 题目链接:21. 合并两个有序链表 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 2.算法原理 1. 递归函数定义与功能 递归函数的主要任务是将两个有序链表合并成一个新的有序链表,并返回合并后…

Git 学习笔记 三个区域、文件状态、分支、常用命令

Git 学习 GitGit概念VS Code中使用仓库(repository)示例 Git 使用时的三个区域示例 Git 文件状态示例 Git 暂存区示例 Git 回退版本删除文件忽略文件示例 分支分支的使用分支的合并与删除分支的合并冲突 Git常用命令Git远程仓库 (HTTP)步骤远程仓库 克隆…

【Linux】Linux命令速查表

Linux 命令列表 – 目录 文件和目录操作命令 文件权限命令文件压缩和归档命令进程管理命令系统信息命令 联网命令 IO重定向命令环境变量命令 用户管理命令 快捷键命令列表 Bash 快捷键命令 Nano 快捷键命令 VI 快捷键命令 Vim 快捷键命令Linux 命令备忘单常见问题解答 1. 文件和…

[linux]信号处理:信号编码、基本API、自定义函数和集合操作的详解

一、信号的概述 1、定义 信号是 Linux 进程间通信的最古老的方式。信号是软件中断,它是在软件层次 上对中断机制的一种模拟,是一种异步(不等待)通信的方式 。信号可以导致一个正在运行的进程被 另一个正在运行的异步进程中断&a…

PyCharm创建一个简单的Django项目

1.Django简介 Django 是一个开放源代码的 Web 应用程序框架,由 Python 编写而成。它遵循 MVC(模型-视图-控制器)的软件设计模式,采用了 MTV(模型-模板-视图)的架构。Django 的设计目标是使开发复杂的、数据…

【MATLAB源码-第162期】基于matlab的MIMO系统的MMSE检测,软判决和硬判决误码率曲线对比。

操作环境: MATLAB 2022a 1、算法描述 MIMO系统(Multiple-Input Multiple-Output,多输入多输出系统)是现代无线通信技术中的关键技术之一,它能够显著增加通信系统的容量和频谱效率,而不需要增加额外的带宽或发射功率。在MIMO系统…

边缘计算全面概述

什么是边缘计算? 边缘计算是一种分布式计算概念,将智能集成到边缘设备(边缘节点)中,使数据能够在数据采集源附近实时处理和分析。由于边缘计算在网络边缘本地处理数据,而不是在云端或集中式数据中心&#…

云端巨擘:大数据与云计算的时代航向

文章目录 大数据时代大数据特点(4v1C大数据与云计算的关系 云计算云计算定义云计算特点云计算分类(服务类型)云计算实现机制云计算体系结构云计算的管理中间件层 大数据时代 大数据定义:海量数据或巨量数据,其规模巨大到无法通过…

学生时期学习资源同步-1 第一学期结业考试题9

原创作者:田超凡(程序员田宝宝) 版权所有,引用请注明原作者,严禁复制转载

ArrayList 是如何进行扩容的?

典型回答 ArrayList 在添加元素时,会自动进行扩容操作,它的执行步骤如下: 当 ArrayList 的内部数组空间不足以容纳新增的元素时,会触发扩容机制。ArrayList 会创建一个新的更大的数组,通常是当前数组长度的 1.5倍 (可…