Max*_*Max 6 c# garbage-collection
我正在玩C#中的垃圾收集器(或者更确切地说是CLR?)试图更好地理解C#中的内存管理.
我制作了一个小样本程序,将三个较大的文件读入byte[]缓冲区.我想看看,如果
byte[]在当前迭代结束后将其设置为null 时,它会产生任何影响GC.Collect()免责声明:我使用Windows任务管理器测量内存消耗并将其四舍五入.我尝试了好几次,但总的来说还是差不多.
这是我的简单示例程序:
static void Main(string[] args)
{
Loop();
}
private static void Loop()
{
var list = new List<string>
{
@"C:\Users\Public\Music\Sample Music\Amanda.wma", // Size: 4.75 MB
@"C:\Users\Public\Music\Sample Music\Despertar.wma", // Size: 5.92 MB
@"C:\Users\Public\Music\Sample Music\Distance.wma", // Size: 6.31 MB
};
Console.WriteLine("before loop");
Console.ReadLine();
foreach (string pathname in list)
{
// ... code here ...
Console.WriteLine("in loop");
Console.ReadLine();
}
Console.WriteLine(GC.CollectionCount(1));
Console.WriteLine("end loop");
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
对于每个测试,我只更改了foreach循环的内容.然后我运行程序,每次Console.ReadLine()停止并检查Windows任务管理器中进程的内存使用情况.我记下了已用过的内存,然后继续程序返回(我知道断点;)).在循环结束后,我写信GC.CollectionCount(1)给控制台,以便了解GC的频率是多少.
foreach ( ... )
{
byte[] buffer = File.ReadAllBytes(pathname);
Console.WriteLine ...
}
Run Code Online (Sandbox Code Playgroud)
结果(使用的内存):
before loop: 9.000 K
1. iteration: 13.000 K
2. iteration: 19.000 K
3. iteration: 25.000 K
after loop: 25.000 K
GC.CollectionCount(1): 2
Run Code Online (Sandbox Code Playgroud)
测试2:
foreach ( ... )
{
byte[] buffer = File.ReadAllBytes(pathname);
buffer = null;
Console.WriteLine ...
}
Run Code Online (Sandbox Code Playgroud)
结果(使用的内存):
before loop: 9.000 K
1. iteration: 13.000 K
2. iteration: 14.000 K
3. iteration: 15.000 K
after loop: 15.000 K
GC.CollectionCount(1): 2
Run Code Online (Sandbox Code Playgroud)
测试3:
foreach ( ... )
{
byte[] buffer = File.ReadAllBytes(pathname);
buffer = null;
GC.Collect();
Console.WriteLine ...
}
Run Code Online (Sandbox Code Playgroud)
结果(使用的内存):
before loop: 9.000 K
1. iteration: 8.500 K
2. iteration: 8.600 K
3. iteration: 8.600 K
after loop: 8.600 K
GC.CollectionCount(1): 3
Run Code Online (Sandbox Code Playgroud)
GC.CollectionCount).怎么会这样?buffer设置null.内存低于测试2.但为什么GC.CollectionCount输出2而不是3?为什么内存使用率不如测试3中的低?buffer设置为null),因此当通过GC.Collect()它调用垃圾收集器时可以释放内存.看起来很清楚.如果有经验丰富的人可以对上述一些观点有所了解,那对我来说真的很有帮助.相当有趣的主题imho.
看看你正在将整个WMA文件读入一个数组,我会说这些数组对象是在大对象堆中分配的.这是一个单独的堆,它以更多malloc类型的方式进行管理(因为压缩垃圾收集在处理大型对象时效率不高).
大对象堆中的空间根据不同的规则收集,并且不计入主要生成计数,并且即使存储器,您也不会看到测试1和2之间的集合数量的差异正在被重用(所有被收集的是Array对象,而不是底层字节).在测试3中,每次循环都会强制收集一个集合 - 大对象堆被包含在其中,因此进程的内存使用量不会增加.
| 归档时间: |
|
| 查看次数: |
1052 次 |
| 最近记录: |