当前位置: 首页 > 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 代码片段?
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • Android 控件背景颜色处理
  • Angular 4.x 动态创建组件
  • Java超时控制的实现
  • JS函数式编程 数组部分风格 ES6版
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • maya建模与骨骼动画快速实现人工鱼
  • Python爬虫--- 1.3 BS4库的解析器
  • Vim 折腾记
  • vuex 笔记整理
  • Vue学习第二天
  • 从PHP迁移至Golang - 基础篇
  • 翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)
  • 计算机在识别图像时“看到”了什么?
  • 排序(1):冒泡排序
  • 区块链分支循环
  • 使用docker-compose进行多节点部署
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (初研) Sentence-embedding fine-tune notebook
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (一)SpringBoot3---尚硅谷总结
  • (转)菜鸟学数据库(三)——存储过程
  • .NET Core 和 .NET Framework 中的 MEF2
  • .net core 依赖注入的基本用发
  • .NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。
  • .NET Framework 4.6.2改进了WPF和安全性
  • .NET/C# 中设置当发生某个特定异常时进入断点(不借助 Visual Studio 的纯代码实现)
  • .Net高阶异常处理第二篇~~ dump进阶之MiniDumpWriter
  • .NET上SQLite的连接
  • @Autowired和@Resource装配
  • @manytomany 保存后数据被删除_[Windows] 数据恢复软件RStudio v8.14.179675 便携特别版...
  • @RequestBody详解:用于获取请求体中的Json格式参数
  • @RequestParam详解
  • @vue/cli 3.x+引入jQuery
  • [ vulhub漏洞复现篇 ] Django SQL注入漏洞复现 CVE-2021-35042
  • [ 转载 ] SharePoint 资料