我注意到很多byte []在分析我的程序时卡在内存中。我做了一些挖掘,发现大多数实例都以某种方式创建:
public byte[] CreateBytes(byte[] bytes)
{
using (var start = new MemoryStream())
{
using (var memStr = new MemoryStream(bytes))
{
//do stuff
return start.ToArray();
}
}
}
然后将返回的byte []传递给其他方法,并用于从另一个使用块中创建另一个MemoryStream
:
using (var uncompressedStream = new MemoryStream(uncompressedData))
{
using (var compressedStream = new MemoryStream())
{
//Do some compression
}
}
myObject.Bytes = uncompressedData;
uncompressedData = null;
return myObject;
(uncompressedData
是从CreateBytes()返回的值。
我的问题是,何时清除byte []?我是否需要将其设置为null,如果是,那么在哪里?在第二个使用块后我不再需要它,但如果我只是放uncompressedData = null;
我不确定是否会回收内存。
我会认为CreateBytes(byte[] bytes)
中的using语句会处理掉字节,但是因为它返回了一个引用会推迟和/或放弃处理吗?
编辑:我添加了另一行代码。由于我将uncompressedBtyes存储在另一个对象中,因此将uncompressedData设置为null是没有意义的,只要myObject
(或直到myObject.Bytes
设置为null),byte []才会生效,对吗?
答案 0 :(得分:5)
当满足两个条件时,字节[]被清除:
GC根据各种因素在非确定性时间运行。
答案 1 :(得分:1)
字节数组与内存中的任何其他托管对象一样,只要不再可以从任何根引用访问,就有资格进行垃圾回收。您可以信任GC以了解何时发生这种情况,并智能地安排时间来实际清理符合条件的对象。尽量不要担心何时实际清理了符合清理条件的对象,GC可能比你更了解。
答案 2 :(得分:0)
除了Erics回答:
如果您确定不再需要byte[]
,请指定null
。
这不能保证现在将回收内存,也不会保证它会在之后重新回放,这只是一种帮助 GC
识别的方法它就像一个收藏主题。
答案 3 :(得分:0)
using
语句实际上与您要返回的byte
数组无关。
MemoryStream
是一次性的,处理该对象是using
语句管理的内容(注意处理与垃圾收集不同,但通常是其前身)。
当你致电ToArray()
时,你正在创造一些不是一次性的新东西;一旦它超出范围,它将在不确定的时间被垃圾收集器清理(这通常是一个很好的优化过程)。