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

25.02.04 《CLR via C#》 笔记14

第二十一章 托管堆和垃圾回收

  1. 内存分配过程 CLR维护一个“下一次分配指针”(NextObjPtr),指向当前托管堆中第一个可用的内存地址
    1. 计算类型所需的字节数,加上对象开销(类型对象指针、同步块索引)所需字节数,检查空间是否足够
    2. 如果空间足够,更新指针到分配的对象末尾
    3. 如果空间不足,触发垃圾回收释放未使用内存
  2. 垃圾回收算法
    1. 把引用类型变量称为根
    2. 标记:暂停所有线程,遍历堆中所有对象,在同步块索引上标记为应该删除(不可达);如果任何根引用了堆上的对象,则标记为可达
    3. 压缩:移动幸存的对象,使它们占用连续的空间(类似碎片整理),同时更新被移动对象的地址
    4. 移动NextObjPtr,指向最后一个幸存对象之后的位置
    5. 如果回收不了内存,说明内存已耗尽,抛出异常
  3. 静态字段引用的对象一直存在,可能会使其引用的对象一直存活,造成内存泄漏
  4. 分代回收算法(原理:新分配的对象生存周期短,老对象生存周期长)
    1. 新创建的对象称为第0代对象,CLR初始化时为第0代选择一个预算容量,当容量不足时触发垃圾回收,幸存的对象就是第1代
    2. 如果根或对象引用了老一代的某个对象,那么可以忽略老对象内部的所有引用;如果老对象引用了新对象,设置了其他机制标记
    3. 如果第1代也用完预算,则变为第2代,同时第0代变为第1代;最高就是第2代,没有第3代
    4. 预算大小是CLR根据每次回收垃圾的多少来动态决定的(启发式算法)
    5. 如果第0代所有对象都是垃圾,可以通过将NextObjPtr移到起始处直接完成垃圾回收
  5. 垃圾回收触发条件
    1. 代码显式调用Collect方法回收(不推荐)
    2. windows报告内存低
    3. CLR卸载AppDomain 执行所有代的回收
    4. CLR关闭 进程终止,由windows回收进程全部内存
  6. 大对象 大于85KB的大对象专门分配在大对象堆,GC不会压缩大对象,大对象总是第2代
  7. 垃圾回收模式
    1. 工作站模式:针对单用户环境优化,单线程垃圾回收,低延迟优先
    2. 服务器模式:针对多用户优化,多线程垃圾回收,堆空间更大,暂停时间较长
  8. 应尽量避免使用Finalize:这个方法在GC结束后调用,由于该方法中可能使用到对象的字段,导致对象在回收时延长了存活时间;Finalize方法的执行时间和顺序是不可控制的;Finalize方法在专用的线程上执行,一旦阻塞则无法调用其他Finalize方法造成内存一直泄露
  9. 封装本机资源时推荐从SafeHandle类派生,以保证本机资源在垃圾回收时释放
  10. IDisposable接口
    1. 如果类定义的一个字段实现了dispose模式,那么类本身也应该实现dispose模式
    2. 对象被显式dispose后,对象本身依然存在
    3. using语句初始化对象,编译器会自动生成try-finally块,并在finally中调用Dispose方法
  11. StreamWriter包装了一个Stream(FileStream或MemoryStream),如果没有显式调用Dispose,会造成缓冲区丢失(StreamWriter不支持终结,就算支持,如果Stream先终结,StreamWriter也无法正确终结)
  12. 本机资源可能占用大量内存,而占用很小的托管内存,为使GC能正确感知内存压力,及时执行垃圾回收,可以使用AddMemoryPressure、RemoveMemoryPressure来修正
  13. Finalize的原理:维护一个终结列表和F-Reachable队列,当对象的实例构造器被调用前,如果定义了Finalize方法,则加入终结列表;被当可终结对象被回收时,离开终结列表进入freachable 队列(此时对象又有引用了(被这个队列引用),不再是垃圾),然后由专用线程调用队列中对象的Finalize方法;调用完成后,对象可能被提升到较老的一代,然后等待下次被回收(此时已经不在终结列表中了,这次会被正常回收)。
  14. GCHandle类提供了对托管对象的直接控制,避免垃圾回收器意外回收对象
    1. 标志位GCHanleType定义

      1. Weak,弱引用,此类型的句柄不会阻止垃圾回收器回收对象。如果对象被垃圾回收,句柄会指向 null,回收后不可访问,无法恢复
      2. WeakTrackResurrection,弱引用,但Finalize调用后仍然可达,在终结器完成之前句柄仍有效
      3. Normal,普通句柄,对象在使用该类型的句柄时不会被垃圾回收,必须手动释放句柄
      4. Pinned,固定句柄,对象固定在内存中,垃圾回收器不能移动它
    2. 弱引用:当对象只通过弱引用被引用时,垃圾回收器会认为该对象是不可达的,从而可以对其进行回收

    3. 用GCHandle创建一个对象的弱引用(Weak),当GCHandle.Target返回null时表示对象已经被回收

    4. 用GCHandle创建一个对象的Normal引用,然后将此对象传给非托管代码,非托管代码就可以使用GCHandle.Target来获取托管对象的指针,这能保证托管对象一直存活、在内存中移动也不丢失;如果已用完,需用Free方法释放

    5. 用GCHandle创建一个对象的Pinned引用,然后用GCHandle.AddrOfPinnedObject获得已固定对象的指针,保证该地址中的数据在内存中不会移动

    6. fixed语句可以直接在unsafe代码块中临时固定对象

    7. ConditionalWeakTable:实现了对Key是弱引用,但只要key未被回收,value一定未被回收

相关文章:

25.02.04 《CLR via C#》 笔记14

第二十一章 托管堆和垃圾回收 内存分配过程 CLR维护一个“下一次分配指针”(NextObjPtr),指向当前托管堆中第一个可用的内存地址 计算类型所需的字节数,加上对象开销(类型对象指针、同步块索引)所需字节数…...

半导体器件与物理篇5 mosfet及相关器件

认识mos二极管 MOS二极管是研究半导体表面特性最有用的器件之一。MOS二极管可作为存储电容器,并且是电荷耦合器件(CCD)的基本结构单元。 MOS二极管结构的重要参数包括:氧化层厚度d;施加于金属平板上的电压V(正偏压时V为正&#x…...

Hugging Face GGUF 模型可视化

Hugging Face GGUF 模型可视化 1. Finding GGUF files (检索 GGUF 模型)2. Viewer for metadata & tensors info (可视化 GGUF 模型)References 无知小儿,仙家雄霸天下,依附强者才是唯一的出路。否则天地虽大,也让你们无路可走&#xff0…...

PVE纵览-掌握 PVE USB 直通:让虚拟机与物理设备无缝连接

PVE纵览-掌握 PVE USB 直通:让虚拟机与物理设备无缝连接 文章目录 PVE纵览-掌握 PVE USB 直通:让虚拟机与物理设备无缝连接摘要前提条件步骤一:识别 USB 设备步骤二:编辑虚拟机配置步骤三:重启虚拟机注意事项其他配置选…...

关于系统重构实践的一些思考与总结

文章目录 一、前言二、系统重构的范式1.明确目标和背景2.兼容屏蔽对上层的影响3.设计灰度迁移方案3.1 灰度策略3.2 灰度过程设计3.2.1 case1 业务逻辑变更3.2.2 case2 底层数据变更(数据平滑迁移)3.2.3 case3 在途新旧流程兼容3.2.4 case4 接口变更3.2.5…...

DeepSeek:智能时代的AI利器及其应用前景

1.DeepSeek是什么? DeepSeek是一款基于人工智能技术的工具,旨在帮助用户高效处理和分析数据、生成内容、优化工作流程等。无论是数据分析、自然语言处理,还是自动化任务,DeepSeek都能提供强大的支持。其核心技术涵盖了机器学习、深…...

超详细UE4(虚幻4)第一人称射击(FPS)游戏制作教程

超详细UE4(虚幻4)第一人称射击(FPS)游戏制作教程 引言 在游戏开发领域,第一人称射击(FPS)游戏一直是最受欢迎的类型之一。从经典的《反恐精英》(CS)到现代的《使命召唤》(Call of Duty),FPS游戏凭借其紧张刺激的游戏体验和高度沉浸感,吸引了无数玩家。如果你是一…...

电商项目高级篇09-检索服务

电商项目高级篇09-检索服务 1、环境搭建1.1、前端静态文件准备1.2、search服务引入模版引擎1.3、index.html页面复制到templates文件夹下1.4、模仿product项目,引入名称空间1.5、动静分离,静态资源路径位置替换1.6、将1.1的静态资源放到nginx目录下1.7、…...

【网络协议大花园】应用层 http协议的使用小技巧,用好了都不用加班,效率翻两倍(下篇)

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. 🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人…...

5 前端系统开发:Vue2、Vue3框架(中):Vue前端工程化组件式开发

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言五、前端工程化(使用Vue创建一个完整的企业级前端项目)1 Vue脚手架(Vue-cli)环境准备(1)…...

【Leetcode刷题记录】1456. 定长子串中元音的最大数目---定长滑动窗口即解题思路总结

1456. 定长子串中元音的最大数目 给你字符串 s 和整数 k 。请返回字符串 s 中长度为 k 的单个子字符串中可能包含的最大元音字母数。 英文中的 元音字母 为(a, e, i, o, u)。 这道题的暴力求解的思路是通过遍历字符串 s 的每一个长度为 k 的子串&#xf…...

Rust中使用ORM框架diesel报错问题

1 起初环境没有问题:在Rust开发的时候起初使用的是mingw64平台加stable-x86_64-pc-windows-gnu编译链,当使用到diesel时会报错,如下: x86_64-w64-mingw32/bin/ld.exe: cannot find -lmysql具体信息很长这是主要信息是rust找不到链…...

Java 数据库连接池:HikariCP 与 Druid 的对比

Java 数据库连接池:HikariCP 与 Druid 的对比 数据库连接池:HikariCP 1. 卓越的性能表现 HikariCP 在数据库连接池领域以其卓越的性能脱颖而出。 其字节码经过精心优化,减少了不必要的开销,使得连接获取和释放的速度极快。 在…...

04树 + 堆 + 优先队列 + 图(D1_树(D7_B+树(B+)))

目录 一、基本介绍 二、重要概念 非叶节点 叶节点 三、阶数 四、基本操作 等值查询(query) 范围查询(rangeQuery) 更新(update) 插入(insert) 删除(remove) 五、知识小结 一、基本介绍 B树是一种树数据结构,通常用于数据库和操作系统的文件系统中。 B树…...

MATLAB实现单层竞争神经网络数据分类

一.单层竞争神经网络介绍 单层竞争神经网络(Single-Layer Competitive Neural Network)是一种基于竞争学习的神经网络模型,主要用于数据分类和模式识别。其核心思想是通过神经元之间的竞争机制,使得网络能够自动学习输入数据的特…...

AITables首发:基于AI全自动推理设计数据库,国内首创,跑5分钟相当于架构师设计一周!

AITables仅运行5分钟,整个系统的表都设计好了! 随着AI大模型技术的开源普及和平民化,现如今任何一个人都有可能成为超级个体。但随着企业级业务的膨胀和业务挑战增多,我们势必要跟上AI发展的节奏,让AI帮我们设计软件。…...

Go语言中结构体字面量

结构体字面量(Struct Literal)是在 Go 语言中用于创建和初始化结构体实例的一种语法。它允许你在声明结构体变量的同时,直接为其字段赋值。结构体字面量提供了一种简洁、直观的方式来创建结构体对象。 结构体字面量有两种主要形式&#xff1…...

PaddleOCR 截图自动文字识别

春节假期在家无聊,撸了三个小工具:PC截图编辑/PC录屏(用于meeting录屏)/PC截屏文字识别。因为感觉这三个小工具是工作中常常需要用到的,github上也有很多开源的,不过总有点或多或少的小问题,不利于自己的使用。脚本的编…...

【Blazor学习笔记】.NET Blazor学习笔记

我是大标题 我学习Blazor的顺序是基于Blazor University,然后实际内容不完全基于它,因为它的例子还是基于.NET Core 3.1做的,距离现在很遥远了。 截至本文撰写的时间,2025年,最新的.NET是.NET9了都,可能1…...

UE求职Demo开发日志#21 背包-仓库-装备栏移动物品

1 创建一个枚举记录来源位置 UENUM(BlueprintType) enum class EMyItemLocation : uint8 {None0,Bag UMETA(DisplayName "Bag"),Armed UMETA(DisplayName "Armed"),WareHouse UMETA(DisplayName "WareHouse"), }; 2 创建一个BagPad和WarePa…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

什么是EULA和DPA

文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...