c# - c#如何删除循环中分配的内存?

标签 c#

想象一下这段代码:

int i=9999999;
while ( i > 1 )
{
    string UnusedMemory="this is a string that eats some ram" + i.ToString();
    i--;
}

如果仅在 GC.Collect() 运行时删除未引用的对象,则此代码应分配大量 ram,直到收集发生。但是它根本没有分配巨大的内存,为什么呢?是否在 IL 级别实现了某种“删除”?还是 GC.Collect() 自动调用得更快?我知道这是一个微不足道的例子,但如果它更复杂并且在该代码块中访问了字符串,它也不会吃掉很多 ram。

编辑:我更改了示例,使字符串始终是唯一的,因此它不能被“缓存”

最佳答案

字符串常量“缓存”在字符串池中,因此每次都是相同的字符串。

如果您对字符串使用方法 String.IsInterned,那么它将返回 true,这意味着它包含在池中。

来自 String.IsInterned :

The common language runtime automatically maintains a table, called the intern pool, which contains a single instance of each unique literal string constant declared in a program, as well as any unique instance of String you add programmatically.

The intern pool conserves string storage. If you assign a literal string constant to several variables, each variable is set to reference the same constant in the intern pool instead of referencing several different instances of String that have identical values.

此外,当需要内存或已分配足够的元素时,GC 会自动调用,因此即使未缓存字符串也不会成为问题。

来自 Fundamentals of Garbage Collection :

当以下条件之一为真时发生垃圾收集:

  • 系统的物理内存不足。
  • 托管堆上分配的对象使用的内存超过了可接受的阈值。这意味着已超过托管堆上可接受的内存使用阈值。该阈值会随着流程的运行不断调整。
  • GC.Collect 方法被调用。几乎在所有情况下,您都不必调用此方法,因为垃圾收集器会连续运行。此方法主要用于特殊情况和测试。

是否可以更改或优化此行为? 是的,在某种程度上:Latency Modes

这个问题与以下内容密切相关: C# memory usage for creating objects in a for loop

关于c# - c#如何删除循环中分配的内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15849383/

相关文章:

c# - itextsharp 在表格单元格中的圆形图像上添加文本

c# - 如何在 Windows 8.1 中捕获高分辨率视频并从中捕获照片。我在尝试时有 UI 跳跃效果

c# - 立即等待异步任务与先声明然后等待

c# - StackExchange.Redis 空闲时间后出现连接问题

c# - 如何将 .cs 输出添加到项目中?

c# - 无法在 .net 核心中发布二进制文件

c# - 字符串到 Ansicode 表示

c# - 是否有任何 "hacks"能够从 main() 返回一个 long?

c# - 我是否需要某种加密类型来连接到 Xamarin 中的外部数据库

c# - 如何从 System.Linq.Expressions.Expression 中删除括号?