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

.NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉

当我们不再使用某个对象的时候,此对象会被 GC 垃圾回收掉。当然前提是你没有写出内存泄漏的代码。我们也知道如果生成了大量的字符串,会对 GC 造成很大的压力。

但是,如果在编译期间能够确定的字符串,就不会被 GC 垃圾回收掉了。


本文内容

    • 示例代码

示例代码

下面,我创建了几个字符串,我关心的字符串是 "walterlv""lindexi" 以及一个当前时间。

于是使用下面的代码来验证:

using System;
using System.Linq;
using System.Runtime.CompilerServices;

namespace Walterlv.Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            var table = new ConditionalWeakTable<string, Foo>
            {
                {"walterlv", new Foo("吕毅")},
                {"lindexi", new Foo("林德熙")},
            };
            var time = DateTime.Now.ToString("T");
            table.Add(time, new Foo("时间"));
            time = null;

            Console.WriteLine($"开始个数:{table.Count()}");
            GC.Collect();
            Console.WriteLine($"剩余个数:{table.Count()}");
        }
    }

    public class Foo
    {
        public string Value { get; }
        public Foo(string value) => Value = value;
    }
}

"walterlv""lindexi" 是在编译期间能够完全确定的字符串,而当前时间字符串我们都知道是编译期间不能确定的字符串。

在 GC 收集之前和之后,ConditionalWeakTable 中的对象数量从三个降到了两个。

运行结果

并没有清除成 0 个,说明字符串现在仍然是被引用着的。

那被什么引用着呢?是字符串暂存池。要理解字符串暂存池,可以阅读我的另一篇博客:

  • .NET/C# 的字符串暂存池

另外,即便设置了 CompilationRelaxations.NoStringInterning,编译期间能确定的字符串在上述代码中也是不会被垃圾回收的。


参考资料

  • c# - Strings and Garbage Collection - Stack Overflow

我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

知识共享许可协议

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

相关文章:

  • .NET/C# 的字符串暂存池
  • 如何为 Win32 的打开和保存对话框编写文件过滤器(Filter)
  • C# 中新增类型的命名空间只需部分与其他命名空间名称相同即可破坏源码兼容性
  • 使用 ProcessMonitor 找到进程所操作的文件的路径
  • MSBuild 在编写编译任务的时候判断当前是否在 Visual Studio 中编译
  • git 配置错误导致无法推送远端仓库?本文介绍各种修复方式
  • WPF 很少人知道的科技
  • WPF 程序的编译过程
  • 制作通过 NuGet 分发的源代码包时,如果目标项目是 WPF 则会出现一些问题(探索篇,含解决方案)
  • .NET 的程序集加载上下文
  • .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • Windows 10 解决无法完整下载安装语言包(日语输入法无法下载使用)
  • 从零开始制作 NuGet 源代码包(全面支持 .NET Core / .NET Framework / WPF 项目)
  • 如何快速创建 Visual Studio 代码片段?
  • css属性的继承、初识值、计算值、当前值、应用值
  • Laravel Mix运行时关于es2015报错解决方案
  • spring boot下thymeleaf全局静态变量配置
  • SwizzleMethod 黑魔法
  • Vue 重置组件到初始状态
  • 闭包--闭包作用之保存(一)
  • 构建二叉树进行数值数组的去重及优化
  • 聚簇索引和非聚簇索引
  • 前端_面试
  • 通信类
  • 无服务器化是企业 IT 架构的未来吗?
  • No resource identifier found for attribute,RxJava之zip操作符
  • postgresql行列转换函数
  • 组复制官方翻译九、Group Replication Technical Details
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • #### go map 底层结构 ####
  • #{} 和 ${}区别
  • #AngularJS#$sce.trustAsResourceUrl
  • #DBA杂记1
  • #微信小程序:微信小程序常见的配置传值
  • $L^p$ 调和函数恒为零
  • (12)Linux 常见的三种进程状态
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (c语言版)滑动窗口 给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (libusb) usb口自动刷新
  • (Python) SOAP Web Service (HTTP POST)
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (翻译)terry crowley: 写给程序员
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (十)c52学习之旅-定时器实验
  • (轉貼) UML中文FAQ (OO) (UML)
  • .net core 源码_ASP.NET Core之Identity源码学习
  • .NET Micro Framework初体验
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .net 提取注释生成API文档 帮助文档
  • .NET国产化改造探索(一)、VMware安装银河麒麟
  • .net企业级架构实战之7——Spring.net整合Asp.net mvc