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

【JVM】垃圾回收 ——自问自答2

Q: System.gc() 的理解

System.gc()底层调用的是 Runtime.getRuntime.gc(),会现实出发FullGC。

但是,它的调用附带一个免责声明,无法保证对垃圾收集器的调用。

Q: 内存溢出和内存泄漏?

内存溢出: 简而言之,内存不够用了
可能因为堆内存在设置大小的时候 -Xms ,-Xmx 设置的比较小
前面也提到,虚拟机栈可以动态扩容时,当物理内存空间不足以给栈扩容,也会导致OutofMemory:stack
在jdk不同版本之中,方法区所产生的OOM是不同的。
jdk7及以前,是永久代 permgen space,而jdk8之后则是 Metaspace

一般情况下,在系统抛出OOM之前,GC会进被触发,尽可能清理出空间给新对象。
比如软引用就是在内存不足的情况下,会被触发回收。


内存泄漏(memory Leak)
当一个对象不会再被程序用到了,但是GC有不能回收他们,此时称之为内存泄漏。(一个不再被使用的对象,仍然有GC roots引用)

内存泄漏的举例:

1、单例模式。
首先明白一个问题,一个JVM对应的是一个进程(有一个与之对应的单例对象 Runtime),
平时说的微服务也好,分布式也好,不管怎样,请搞清楚。一个java进程,对应一个JVM,或者可以理解为,一个运行起来的服务,它就是一个进程。
如果在这个服务(进程)中,有一个单例对象,那么此对象的生命周期是随着JVM进程的消亡而消亡的。
如果此时单例对象内强引用了一个其他对象,而没有手动释放,那么这个被引用的对象的生命周期会和引用它的单例对象一样,一直随着JVM进程结束,才能结束。
如果这个被引用的对象后续不再被使用,但是它无法被GC销毁,这时候,就是个典型的内存泄漏场景。
我们可以用软引用来解决这种问题。

2、没用关闭某些资源
java的面向对象思想,把很多资源使用场景都有一个建立链接和关闭链接的过程,这个其实是一种网络分层模型中,提供可靠服务的前提。
比如数据库链接,套接字链接(socket),IO,他们都是要进行手动close的。前两个其实都是基于TCP的建立连接和关闭链接的过程。


Q: 谈一谈Stop the World

STW GC线程在工作的过程中,与用户线程是并发执行的,二者抢占CPU资源,GC执行,用户线程被暂停。
 
 可达性分析算法中枚举根节点会导致Java执行线程停顿。
 因为: 分析工作要保证一致性结果,一般是在当前进程快照中分析
 如果分析过程中,一直有用户线程在执行,就会导致分析结果不准确。
 
 (开发中尽量少使用System.gc 会产生STW)
 
 
 
 
 
 Q: 垃圾回收的并行,并发。
 
 垃圾回收事件的并行与串行是对立的,它描述的是垃圾收集线程的工作关系。
 串行,指在进行垃圾收集时,只有一个GC线程在工作。
 并行:指在进行垃圾收集时,有多个GC线程在同时工作。
 注意上述两个场景中,用户线程都是暂停的,并行与串行机制只是在描述垃圾收集线程。
 
 但是请注意一点:并行,虽说是要建立在多处理器条件下,才可能发生的,但是在操作系统相关的知识体系中,“并行”的概念并不是绝对的。
 因为并行的垃圾回收行为,在单处理器环境下,是通过并发执行表现的。但是请注意发生CPU争抢的,只有GC线程而没有用户线程。
 
 这个道理其实就像理解操作系统的共享特性。共享分为独占式共享,和同时共享。
 独占式共享,就是串行的,一个作业完成对资源的使用后,再运行下一个作业去访问资源。
 但是同时访问共享,并不真是"同时访问",本质上来说,也是通过并发的特性来实现"同时"。
 
 
 
 垃圾收集的并发行为:
 
指的是垃圾收集线程,可以和用户线程 "同时"执行(这里的同时,和上面的解释是一样的,还是取决于CPU和工作线程的个数)

因此,垃圾收集上下文环境所说的并发和并行,和操作系统层面说的并发,并行是有区别的。

Q: 安全区和安全点
程序执行时并不是在任何地方都能停下来开始GC,只是在特定位置才能停顿下来,开始GC,这些位置称为 安全点

安全点的选择一般是以"是否具有让程序长时间执行的特征",比如选择一些执行时间较长的指令作为安全点,比如方法调用,循环跳转和异常跳转。

如何在GC发生时,检查所有线程都跑到了最近的安全点停顿下来呢?
1、抢占式中断:弃用
2、主动式中断:设置标志位,各个线程运行到Safepoint,主动轮训这个标志,若中断标志为真,将自己进行中断挂起。

这里补充一个操作系统的知识

进程在执行的过程时,CPU会有内核态和用户态,当发生系统中断,CPU会从用户态转换为内核态,使操作系统夺回CPU控制权(也是唯一途径)
内核态->用户态:执行一条特权指令----修改PSW的标志位为用户态。操作系统让出CPU使用权。
用户态->内核态:由 中断 引发,硬件自动完成变态过程。
中断分为 内中断和外中断,一般程序执行遇到异常,或请求系统调用,执行访管指令都属于内中断。
当进入中断时,用户进程根据不同场景会进入就绪,阻塞,就绪/阻塞挂起,退出等状态。

操作系统关于线程实现方式有三类:内核级线程、用户级线程、组合方式

用户级线程:(图片来自王道,侵删)

早期,操作系统只支持进程,没用线程的概念,内核中只有进程的概念,进程作为资源分配的单位,
用户通过线程库来对一个进程进行拆分执行。最简单的线程库,可以理解为:

int main(){int flag =0;while(true){if(flag==0){do A;}if(flag==1){do B;}if(flag==3){do C;}}}

用户线程是建立在用户空间的线程库上,系统内核不感知线程存在的实现,用户线程的创建、同步、销毁和调度完全在用户状态中完成。
但是这种设计的时间片划分仍然是以进程为单位的,进程A有一个线程,进程B有100个线程,假设两者的时间片长度相同,这种分配结果是不公平的。
而且,某一线程被阻塞,整个进程都会被阻塞,内核分配CPU资源也是按进程分配,也就是说进程B中的所有线程都是并发执行,每次只能执行1个线程。


内核级线程

操作系统内核支持的线程,这种线程有内核来完成线程切换。每个线程都有自己的TCB
换句话说,操作系统内核已经支持线程的概念了,内核已经将线程作为最小的资源分配单位。


用户线程的实现是通过线程库来创建管理的,线程库分为有内核支持和无内核支持,区别在于在调用库内函数时,是否需要进行内核的系统调用。
java线程库就是常用的线程库之一。它以来与宿主系统的线程库,windows上是 windows API,Unix上是POSIX pthreads。

这些模型是建立在支持内核级线程的系统中的:

多线程模型
用户线程和内核线程链接方式不同,分为一对一,多对一,多对多。

一对一:一个用户线程对应一个内核线程,用户线程被阻塞,并不会影响其他线程的运行。
并发能力较强,一个线程阻塞,并不会影响到其他线程,但是一一对应开销也很大。(见上图)

多对一:一个内核线程对应多个用户线程,这些线程一般属于一个进程,线程的调度和管理都是在用户空间完成的(执行效率比较高)。
缺点很突出:任意时刻,只能有一个线程与内核线程进行映射,一个线程阻塞,整个进程会发生阻塞,多个线程不能同时在多个处理器上运行。

java每个线程都对应了一个本地线程,其实java的线程是在JVM虚拟机中通过一些C++写的方法调用,来调用本地线程库的API,对线java程状态进行管理,映射。
所有这个对应的本地线程,实际上是本地线程库中的用户级的线程,而非内核线程,至于本地线程库到底使用了那种多线程模型,要具体系统具体分析,这也是JVM实现跨平台的一个手段。

这里补充这些知识,是想说,用户线程在安全点的STW,其受到中断而挂起,其实是通过

JVM——本地线程库——内核级线程状态切换  这一套执行流程的。这个安全点造成的中断,并非操作系统里说的中断,OS里的中断粒度是针对进程来说的。

安全区:

如果某些线程在准备进入安全点之前,是阻塞态,该线程此时是无法响应JVM的中断请求的,运行到安全点,再中断挂起,
安全区是一段代码片段中,对象的引用关系没有发生变化,再这个区域中任何位置开始GC都是安全的。
从一个点 被扩大成了一个片段。

执行过程:
当线程运行到safe Region代码段时,首先标识已经进入了safe Region,若这段时间内发生GC,JVM会忽略标识为 safe Region状态的线程。

当线程即将离开safe Region时,会检查JVM是否已经完成GC,若完成了,则继续运行,否则线程必须等待到收到可以安全离开safe Region的信号为止。

Q: 强软弱虚来一套

强引用:普通创建对象的语法,都是强引用。
软引用:堆内内存不足时,软引用会被回收
弱引用:发生垃圾回收行为时,一定会被回收
虚引用:一个对象是否有虚引用存在,跟其生存时间没叼毛影响,无法通过一个虚引用获取一个对象实例。
设置虚引用的目的在于垃圾回收该对象时,得到一个系统通知。它其实可以理解为一个对象回收的跟踪。对象回收后,将虚引用加入引用队列,以通知程序该对象的回收情况

//-xms9m -xmx9M  -XX:+PrintGCDetailsclass ReferenceDemo{//强引用,ReferenceDemo对象实例化后,objRf_inheap位于实例对象所在的堆空间中Object objRf_inheap =new Object();public void foo(){//强引用,引用存在于局部变量表中的第二个位置,slot标号为1 Object objRf_inLV =new Object();//软引用,当内存空间不足的时候,会在GC中对其进行回收Object obj =new Object();SoftReference obj_softRf =new SoftReference<Object>(obj);obj=null;//可以获取代到软引用包装的对象obj_softRf.get();//创建一个大对象,当前堆装不下了,目的是要触发GC,堆内内存不足时,软引用会被回收byte[] buffers =new byte[7*1024*1024];....
}@Override
protected void finalize() throws Throwable {super.finalize();System.out.println("我被调用了呀!!!!");
}
}

相关文章:

【JVM】垃圾回收 ——自问自答2

Q: System.gc() 的理解 System.gc()底层调用的是 Runtime.getRuntime.gc(),会现实出发FullGC。 但是&#xff0c;它的调用附带一个免责声明&#xff0c;无法保证对垃圾收集器的调用。 Q&#xff1a; 内存溢出和内存泄漏&#xff1f; 内存溢出&#xff1a; 简而言之&#xf…...

MySQL数据库数据类型

MySQL数据库数据类型分类 在MySQL数据库中&#xff0c;MySQL数据类型分有四大类&#xff1a;数值类型、文本/二进制类型、时间日期和String类型。以下是这四大类的具体类型&#xff1a; 数值类型 数值类型的范围和字节大小&#xff1a; tinyint类型 tinyint类型只有一个字节…...

【力扣】27. 移除元素 <快慢指针、首尾指针>

【力扣】27. 移除元素 给你一个数组 nums 和一个值 val&#xff0c;你需要原地移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。不要使用额外的数组空间&#xff0c;必须仅使用 O(1) 额外空间并原地修改输入数组。元素的顺序可以改变。你不需要考虑数组中超…...

【每日一题】—— C. Challenging Cliffs(Codeforces Round 726 (Div. 2))

&#x1f30f;博客主页&#xff1a;PH_modest的博客主页 &#x1f6a9;当前专栏&#xff1a;每日一题 &#x1f48c;其他专栏&#xff1a; &#x1f534; 每日反刍 &#x1f7e1; C跬步积累 &#x1f7e2; C语言跬步积累 &#x1f308;座右铭&#xff1a;广积粮&#xff0c;缓称…...

想在金融界拥有一席之地吗—社科院杜兰大学金融管理硕士助你圆梦

追求高学历是为了什么&#xff1f;一纸证书吗&#xff1f;显然并非如此&#xff0c;只有读过研的人才有话语权。在上升一个平台后&#xff0c;你必然会发现&#xff0c;更高学历得到的不止是一张文凭。而是更大的平台、更广阔的视野、更包容的环境&#xff0c;更多样的文化。最…...

Moonbeam与Nodle网络集成,增添物联网功能

领先的波卡跨链互连开发平台Moonbeam近期宣布与Nodle Network达成XCM集成&#xff0c;将NODL Token带到Moonbeam生态之中。本次集成将会开启波卡中Moonbeam和Nodle网络以及通过Moonbeam互连合约相连的远程链之间的流动性。 Nodle网络是一个为物联网&#xff08;Internet of Th…...

关于docker 在ubuntu16.04 上的安装

https://www.sohu.com/a/708313241_121368355 参考教程&#xff1a; https://www.runoob.com/docker/docker-image-usage.html 镜像网址 https://hub.docker.com/...

Cmder启动加速

Cmder是一个比较好用的命令行工具&#xff0c;可以通过修改默认Git地址提高启动速度&#xff1a; 打开vendor/init.bat添加本机Git地址&#xff0c;并且打开启动时间显示 :: Use /v command line arg or set to > 0 for verbose output to aid in debugging. set GIT_INSTA…...

【windows】windows上如何使用linux命令?

前言 windows上的bat命令感觉不方便&#xff0c;想在windows上使用linux命令。 有人提供了轮子&#xff0c;本文简单介绍一些该轮子的安装与使用&#xff0c;希望能够帮助到和我有一起需求的网友。 我的答案是busybox。 1.安装busybox.exe 在这个网站上安装busybox busyb…...

Docker Compose: 集合管理Docker的工具安装

Docker Compose:集合管理多个Docker容器的工具&#xff0c;在安装docker时windows,macos默认安装Docker Compose&#xff0c;linux需要自己手动安装 去官网https://github.com/docker/compose/releases下载需要的版本$ sudo chmod x ./docker-compose-linux-x86_64$ sudo cp .…...

Jmeter(三) - 从入门到精通 - 测试计划(Test Plan)的元件(详解教程)

1.简介 上一篇中已经教你如何通过JMeter来创建一个测试计划&#xff08;Test Plan&#xff09;&#xff0c;那么这一篇我们就将JMeter启动起来&#xff0c;创建一个测试计划&#xff08;Test plan&#xff09;&#xff0c;然后给大家介绍一下测试计划&#xff08;Test Plan&am…...

20天学会rust(一)和rust say hi

关注我&#xff0c;学习Rust不迷路 工欲善其事&#xff0c;必先利其器。第一节我们先来配置rust需要的环境和安装趁手的工具&#xff0c;然后写一个简单的小程序。 安装 Rust环境 Rust 官方有提供一个叫做 rustup 的工具&#xff0c;专门用于 rust 版本的管理&#xff0c;网…...

嵌入式传感器将是未来智能交通发展的关键

随着移动即服务&#xff08;MaaS&#xff09;被视为智能移动的关键要素&#xff0c;对增长至关重要的一大因素是机器人车辆技术&#xff0c;而机器人技术又将高度依赖嵌入式传感器。 在这种情况下&#xff0c;高端传感器技术和原始计算能力将成为持续不断的市场扰乱的核心&…...

Vue3 实现产品图片放大器

Vue3 实现类似淘宝、京东产品详情图片放大器功能 环境&#xff1a;vue3tsvite 1.创建picShow.vue组件 <script lang"ts" setup> import {ref, computed} from vue import {useMouseInElement} from vueuse/core/*获取父组件的传值*/ defineProps<{images:…...

机器学习笔记 - 使用 YOLOv5、O​​penCV、Python 和 C++ 检测物体

一、YOLO v5简述 YOLO v5虽然已经不是最先进的对象检测器,但是YOLOv5 使用了一个简单的卷积神经网络 CNN架构(相对YOLO v8来讲,不过v8精度是更高了一些),更易理解。这里主要介绍如何轻松使用 YOLO v5来识别图像中的对象。将使用 OpenCV、Python 和 C++ 来加载和调用我们的…...

使用手机相机检测电脑屏幕刷新率Hz

使用手机相机检测电脑屏幕刷新率Hz 1、电脑打开https://www.testufo.com/frameskipping 2、相机专业模式&#xff1a;快门1/10、ISO自动&#xff0c;拍摄一张照片。120Hz至少要有12个亮块&#xff0c;50Hz至少有6个亮块。 更改刷新速率 1、选择 “开始>设置>系统>显示…...

修改k8s pod的挂载目录

1、找到挂载的服务 kubectl get service2、编辑pod的环境配置 kubectl edit deployment vendor-basic-bill-executor3、找到需要挂载的目录...

Vue3+SpringBoot快速开发模板

起因&#xff1a;个人开发过程经常会使用到Vue3SpringBoot技术栈来开发项目&#xff0c;每次在项目初始化时都需要涉及一些重复的整理工作&#xff0c;于是结合一些个人觉得不错的前后端模板进行整合&#xff0c;打通一些大多数项目都需要的实现的基础功能&#xff0c;以便于快…...

CSDN竞赛68期

CSDN竞赛68期 CSDN竞赛68期1.小球游戏2.王子闯闸门分析 CSDN竞赛68期 1.小球游戏 这个是64期的题目&#xff0c;完全一样&#xff0c;有点无语了&#xff0c;竟然又出了&#xff0c;真不知道怎么出的题。 参考&#xff1a;CSDN周赛64期 2.王子闯闸门 波斯王子要去救被贾法尔…...

Redis入门

目录 一、Redis简介 二、主要特点 三 、Redis的下载与安装 1.2.1 Redis下载 1.2.2 Redis安装 1.3 Redis服务启动与停止 1.3.1 服务启动命令 1.3.2 客户端连接命令 1.3.3 修改Redis配置文件 1.3.4 Redis客户端图形工具 一、Redis简介 Redis是一个基于内存的key-value…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...