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

【Java从入门到放弃 之 GC】

垃圾回收

  • 垃圾回收
  • 什么是垃圾
    • 引用计数法
    • 可达性分析算法
  • 垃圾回收算法
    • 标记清除法
    • 标记复制法
    • 标记整理法
    • 分代
  • 常用的垃圾回收器

垃圾回收

如果你学过C++,你肯定知道,我们没申请一块内存,都要自己写回收内存的方法。而Java不需要我们管理内存,因为Java有垃圾回收器。那么说到垃圾回收器,就牵扯到三个问题:

  1. 什么是垃圾
  2. 什么时候回收垃圾
  3. 怎么回收

什么是垃圾

首先我们要了解Java运行时内存,我们关注的点主要在堆区与方法区。 栈区的内存基本是类结构确定的时候就确定下来了。那么我们说的垃圾回收,是回收这两个区域的不再使用的对象。
那么如何确定对象是不再使用的,或者说是死对象?

引用计数法

引用计数法就是:在对象中增加一个引用计数器,每当有其他对象引用这个对象的时候,计数器就加一;当不再引用这个对象的时候,计数器减一;计数器为0的时候就代表这个对象不再被使用了。
这个方法是比较简单的方法,其实很多时候我们遇到问题,想到的最朴素的思想,有的时候效率其实也不是不错的。因为原理简单,所以效率其实也是很高的。但是这个方法其实没有在Java的实际的垃圾回收器中大范围使用,主要原因是,引用计数法解决不了循环引用的问题。
循环引用就是A对象引用B对象,B对象也引用A对象,两个对象互相持有对方的实例引用。

可达性分析算法

可达性分析算法:这个算法的核心是通过一系列GC root根对象开始进行深度搜索,每一个root对象深度搜索都会拉出来一个引用链条,在这些链条上的对象属于活对象,不在这些引用链条的对象就是死对象,也就是我们垃圾回收的对象。

垃圾回收算法

标记清除法

最基础的垃圾收集算法是标记清楚算法,这个算法由List之父John McCarthy提出,首先标记出需要回收的对象,然后在标记完成之后,统一回收所有的被标记的对象。

算法特点:

  1. 实现简单
  2. 执行效率不稳定,因为算法分为两个步骤,一个标记一个清楚,都是跟对象的数量相关的;
  3. 最大的缺点是会产生内存碎片,而碎片太多会导致之后程序需要一个连续的大内存的时候找不到连续的内存地址,又得触发一次新的内存回收

标记复制法

标记复制法是由1969年Fenichel提出的一种半区复制的垃圾收集算法,它将可用内存分为大小相等的两块,每次只使用一块。当这一块的内存使用完,就把还存活的对象复制到另一半内存上,然后把这一半内存清理掉。

算法特点:

  1. 可以有效地避免标记清除法带来地内存碎片的问题
  2. 浪费了一般的空间,适用于新生代对象朝生夕死的情况

标记整理法

标记复制法在对象存活率比较高的时候,需要进行比较多的复制操作,所以一般在老年代一般不采用这种算法。1974年Edward Lueders提出一种标记整理法的算法。标记的过程跟标记清楚法一样,但是后续为了避免出现内存碎片,这个算法要求让所有存活的对象都向内存空间的一端移动,最后直接清楚调边界外的内存。

算法特点:

  1. 避免产生内存碎片
  2. 移动对象的时候,需要更新所有指向改对象的引用,增加了复杂度

分代

基于对象的生命周期不同,将垃圾回收空间分为多个区域,不同区域采用不同的回收策略

  1. 新生代: 通常包含最新的对象,默认采用标记复制算法回收这种短命的对象
  2. 老年代: 存活时间比较长的对象,一般采用标记整理法或者标记清楚法

常用的垃圾回收器

根据不同的垃圾回收算法和应用场景,JVM 提供了多种垃圾回收器供选择:

  1. Serial 收集器
    特点:单线程工作,适合客户端模式下的小型应用程序。
    适用场景:桌面应用、嵌入式设备。
  2. Parallel 收集器
    特点:多线程并行工作,专注于提高吞吐量。
    适用场景:服务器端应用,对响应时间要求不高但希望最大化 CPU 利用率。
  3. CMS(Concurrent Mark-Sweep)收集器
    特点:并发工作,尽量减少停顿时间。
    适用场景:Web 应用,对响应时间敏感的应用程序。
  4. G1(Garbage First)收集器
    特点:分区收集,综合考虑吞吐量和延迟,支持细粒度的垃圾回收。
    适用场景:大型应用,具有较大的堆内存配置。

相关文章:

【Java从入门到放弃 之 GC】

垃圾回收 垃圾回收什么是垃圾引用计数法可达性分析算法 垃圾回收算法标记清除法标记复制法标记整理法分代 常用的垃圾回收器 垃圾回收 如果你学过C,你肯定知道,我们没申请一块内存,都要自己写回收内存的方法。而Java不需要我们管理内存&…...

【C++】等差数列末项计算题解析及优化

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯题目描述与输入输出要求💯数学分析与公式推导公差的计算通项公式推导 💯示例解析解题步骤 💯程序实现与解析初版代码代码解析优点与不足…...

vue中父组件接收子组件的多个参数的方法:$emit或事件总线

方法一&#xff1a;使用 $emit 方法 原理 子组件通过 $emit 方法向父组件发送事件&#xff0c;同时可以传递多个参数&#xff0c;父组件通过事件监听来接收这些参数。 示例 子组件代码 <template><div><button click"sendData">发送数据</…...

2024.12.10——攻防世界Web_php_include

知识点&#xff1a;代码审计 文件包含 伪协议 伪协议知识点补充&#xff1a; 在PHP中&#xff0c;伪协议&#xff08;Pseudo Protocols&#xff09;也被称为流包装器&#xff0c;这些伪协议以 php://开头&#xff0c;后面跟着一些参数&#xff0c;用于指定要执行的操作或需要…...

【机器学习算法】——数据可视化

1. 饼图&#xff1a;显示基本比例关系 import matplotlib.pyplot as pltplt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False# ——————————————————————————————————————————————————————…...

如何在 Android 项目中实现跨库传值

背景介绍 在一个复杂的 Android 项目中&#xff0c;我们通常会有多个库&#xff08;lib&#xff09;&#xff0c;而主应用程序&#xff08;app&#xff09;依赖所有这些库。目前遇到的问题是&#xff0c;在这些库中&#xff0c;libAd 需要获取 libVip 的 VIP 等级状态&#xf…...

JavaCV之FFmpegFrameFilter视频转灰度

1、代码 package com.example.demo.ffpemg;import lombok.SneakyThrows; import org.bytedeco.javacv.*;public class FFmpegFrameFilterVideoExample {SneakyThrowspublic static void main(String[] args) {// 输入视频文件路径String inputVideoPath "f:/2222.mp4&qu…...

Redis:基于PubSub(发布/订阅)、Stream流实现消息队列

Redis - PubSub、Stream流 文章目录 Redis - PubSub、Stream流1.基于List的消息队列2.基于PubSub的消息队列3.基于Stream的消息队列1.Redis Streams简介2.Redis Streams基本命令1.XADD 添加消息到末尾2.XLEN 获取消息长度3.XREAD 读取消息 &#xff08;单消费模式&#xff09;4…...

C#飞行棋(新手简洁版)

我们要在主函数的顶部写一些全局静态字段 确保能在后续的静态方法中能够获取到这些值和修改 static int[] Maps new int[100];static string[] PlayerName new string[2];static int[] PlayerScore new int[2];static bool[] Flags new bool[2] {true,true }; static int[]…...

【OpenCV】图像转换

理论 傅立叶变换用于分析各种滤波器的频率特性。对于图像&#xff0c;使用 2D离散傅里叶变换&#xff08;DFT&#xff09; 查找频域。快速算法称为 快速傅立叶变换&#xff08;FFT&#xff09; 用于计算DFT。 Numpy中的傅立叶变换 首先&#xff0c;我们将看到如何使用Numpy查…...

力扣 重排链表-143

重排链表-143 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(next)…...

【Kubernetes理论篇】容器集群管理系统Kubernetes(K8S)

Kubernetes集群部署基本管理实战 这么好的机会&#xff0c;还在等什么&#xff01; 01、Kubernetes 概述 K8S是什么 K8S 的全称为 Kubernetes (K12345678S)&#xff0c;PS&#xff1a;“嘛&#xff0c;写全称也太累了吧&#xff0c;写”。不如整个缩写 K8s 作为缩写的结果…...

Kubernetes 常用操作大全:全面掌握 K8s 基础与进阶命令

Kubernetes&#xff08;简称 K8s&#xff09;作为一种开源的容器编排工具&#xff0c;已经成为现代分布式系统中的标准。它的强大之处在于能够自动化应用程序的部署、扩展和管理。在使用 Kubernetes 的过程中&#xff0c;熟悉常用操作对于高效地管理集群资源至关重要。本文将详…...

爬虫基础之Web网页基础

网页的组成 网页可以分为三大部分–HTML、CSS 和 JavaScript。如果把网页比作一个人&#xff0c;那么 HTML 相当于骨架、JavaScript 相当于肌肉、CSS 相当于皮肤&#xff0c;这三者结合起来才能形成一个完善的网页。下面我们分别介绍一下这三部分的功能。 HTML HTML(Hypertext…...

k8s, deployment

控制循环&#xff08;control loop&#xff09; for {实际状态 : 获取集群中对象X的实际状态&#xff08;Actual State&#xff09;期望状态 : 获取集群中对象X的期望状态&#xff08;Desired State&#xff09;if 实际状态 期望状态{什么都不做} else {执行编排动作&#xf…...

使用ensp搭建OSPF+BGP和静态路由,底层PC使用dhcp,实现PC互通

1.4种方式&#xff0c;实现PC2可以互通底层的所有设备 OSPF&#xff1a;OSPF是一种用于互联网协议网络的链路状态路由协议 BGP&#xff1a;是一种用于互联网上进行路由和可达性信息传递的外部网关协议&#xff08;EGP&#xff09; 静态路由&#xff1a; 静态路由是一种路由方…...

TÜLU 3: Pushing Frontiers in Open Language Model Post-Training

基本信息 &#x1f4dd; 原文链接: https://arxiv.org/abs/2411.15124&#x1f465; 作者: Nathan Lambert, Jacob Morrison, Valentina Pyatkin, Shengyi Huang, Hamish Ivison, Faeze Brahman, Lester James V. Miranda, Alisa Liu, Nouha Dziri, Shane Lyu, Yuling Gu, Sau…...

深入解读 MySQL EXPLAIN 与索引优化实践

MySQL 是当今最流行的关系型数据库之一&#xff0c;为了提升查询性能&#xff0c;合理使用 EXPLAIN 工具和优化索引显得尤为重要。本文将结合实际示例&#xff0c;探讨如何利用 EXPLAIN 分析查询执行计划&#xff0c;并分享索引优化的最佳实践。 一、EXPLAIN 工具简介 EXPLAIN …...

Flume——进阶(agent特性+三种结构:串联,多路复用,聚合)

目录 agent特性ChannelSelector描述&#xff1a; SinkProcessor描述&#xff1a; 串联架构结构图解定义与描述配置示例Flume1&#xff08;监测端node1&#xff09;Flume3&#xff08;接收端node3&#xff09;启动方式 复制和多路复用结构图解定义描述配置示例node1node2node3启…...

ragflow连ollama时出现的Bug

ragflow和ollama连接后&#xff0c;已经添加了两个模型但是ragflow仍然一直warn&#xff1a;Please add both embedding model and LLM in Settings &#xff1e; Model providers firstly.这里可能是我一开始拉取的镜像容器太小&#xff0c;容不下当前添加的模型&#xff0c;导…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

Bean 作用域有哪些?如何答出技术深度?

导语&#xff1a; Spring 面试绕不开 Bean 的作用域问题&#xff0c;这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开&#xff0c;结合典型面试题及实战场景&#xff0c;帮你厘清重点&#xff0c;打破模板式回答&#xff0c…...

数据结构:递归的种类(Types of Recursion)

目录 尾递归&#xff08;Tail Recursion&#xff09; 什么是 Loop&#xff08;循环&#xff09;&#xff1f; 复杂度分析 头递归&#xff08;Head Recursion&#xff09; 树形递归&#xff08;Tree Recursion&#xff09; 线性递归&#xff08;Linear Recursion&#xff09;…...

Android写一个捕获全局异常的工具类

项目开发和实际运行过程中难免会遇到异常发生&#xff0c;系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler&#xff0c;它是Thread的子类&#xff08;就是package java.lang;里线程的Thread&#xff09;。本文将利用它将设备信息、报错信息以及错误的发生时间都…...

高防服务器价格高原因分析

高防服务器的价格较高&#xff0c;主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因&#xff1a; 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器&#xff0c;因此…...

OCR MLLM Evaluation

为什么需要评测体系&#xff1f;——背景与矛盾 ​​ 能干的事&#xff1a;​​ 看清楚发票、身份证上的字&#xff08;准确率>90%&#xff09;&#xff0c;速度飞快&#xff08;眨眼间完成&#xff09;。​​干不了的事&#xff1a;​​ 碰到复杂表格&#xff08;合并单元…...