A | B | C | NextObjPtr |
---|---|---|---|
--- | -- | ---- | -------------------- |
CLR提供0-2一共三个堆(逻辑上的),每个堆的大小有预算且是动态的。
heap0, heap1, heap2
function Alloc(size)
if heap0.avaliSpace < size then
--对0号堆进行一次GC
local activeObjs = heap0:Collect()
-- 0号中堆剩下的对象紧凑排列后移入1号堆
heap1:AddObjs(activeObjs)
if heap1.avaliSpace < 0 then
-- 对1号堆进行一次GC
activeObjs = heap1:Collect()
-- 1号堆剩下的对象紧凑排列后移入2号堆
heap2:AddObjs(activeObjs)
if heap2.avaliSpace < 0 then
-- 回收二代堆,压缩存活对象
heap2:Collect()
end
end
end
if heal0.avaliSpace >= size then
return heap0:Alloc(size)
else
error('no enough space')
else
end
在这一过程中,可能会动态调整各堆的预算。
SafeHandle
包装native resource handleIDisposable
接口控制本地资源生存期IDisposable
,那么类也需要实现,在Dispose
方法中调用字段的Dispose
方法ObjectDisposedException
Dispose
方法实现线程安全,而是在调用处保证没有其他线程在同时调用Dispose
方法的方式
finally
代码块中调用Dispose
csharp var fs = new FileStream("temp.dat", FileMode.Create); try { fs.Write(bytes, 0, bytes.Length); } finally { if (fs != null) fs.Dispose(); }
使用using
简化代码,两者是等价的
csharp using (var fs = new FileStream("temp.dat", FileMode.Create) { fs.Write(bytes, 0, bytes.Length); }
FileStream
与StreamWriter
FileStream
包含一个缓冲区对象StreamWriter
也包含一个缓冲区对象StreamWriter.Dispose
对调用绑定FileStream
的Dispose
方法StreamWriter
的Finalize
函数中不再向FileStream
中写入缓存的数据,会造成数据的丢失当GC到拥有Finalize方法的对象时
public static GCHandle GCHandle.Alloc(object value, GCHandleType type);
csharp var obj = new byte[1000]; var handle = GCHandle.Alloc(obj, GCHandleType.Pinned); SomeNativeMethod(handle.ToIntPtr()); // 异步使用完毕后,调用Free handle.Free();
fixed
关键字进行内存固定(尝试了下发现必须在unsafe代码块中使用)csharp var bytes = new byte[1000] fixed(byte* pBytes = bytes) { SomeNativeMethod((IntPtr)pBytes); }
弱引用住一个对象
```csharp
var obj = new object();
var handle = GCHandle.Alloc(obj, GCHandleType.Weak);
var obj = handle.Target;
``1. 可以使用
WeakReference`简化使用方法
原文:https://www.cnblogs.com/hamwj1991/p/12384395.html