如何确保将对象添加到SerializationInfo
对象中?
例如:如果我在信息对象中添加一个哈希表,我如何确保在序列化之后,我的类的hastable对象没有活着的引用,我可以以某种方式释放内存?
info.AddValue("attributesHash", attributesHash, typeof(System.Collections.Hashtable));
更新(代码)
[Serializable]
class A : System.Runtime.Serialization.ISerializable
{
List<int> m_Data = new List<int>();
//...
public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
{
if (m_Data != null)
{
info.AddValue("MyData", m_Data, typeof(List<int>));
m_Data.Clear();
}
m_Data = null; // <-- Will this be collected by GC?
GC.GetTotalMemory(true); //forced collection
}
};
我的问题是:如果我在添加到信息列表后使我的对象为null,它将在调用序列化后释放(当信息被销毁时 - 我希望),或者在调用GC的函数时(在我的行中)不这么认为)?
如果设置'm_Data = null'不会将其标记为垃圾,那么我怎么知道m_Data占用的内存是否已被释放?
答案 0 :(得分:2)
“我可以以某种方式释放记忆”而“物品被处置”并不顺利。
内存管理由GC完成。只要没有对象的引用,它就会被标记为垃圾收集。因此它处理托管资源。
然而,处置是完全不同的动物,并且在实现IDisposable的类型上调用Dispose()并处理非托管资源,例如文件句柄和窗口资源。
你需要明确你的意思。
答案 1 :(得分:0)
您需要使您的包含对象实现IDisposable。但仅仅因为你已经被序列化并不意味着你也需要被处置。然后,引用对象应该在序列化后调用dispose,如果这是预期的那样。
对于反序列化的对象,它也应该在它被使用时通过它的任何引用来处理(可能在另一个appdomain中?)。所以这意味着两个实例都需要处理。如果您共享的资源是单个实例(例如IntPtr),那么您可能需要更加聪明,例如不使用此对象处理该非托管资源,而是从更高级别处置。
一般经验法则:创造它的人,处理它。
IDisposable documentation所描述的另一种常见模式是将Dispose()调用到对象析构函数中。这将为您提供非确定性的处理时间,但保证可以正常工作(假设您没有参考泄漏)。
答案 2 :(得分:0)
经过大量分析后,我不认为GC会在请求时收集内存...至少在GetTotalMemory函数的情况下不会。
将对象设置为null会将其标记为垃圾,但这并不意味着它会立即收集。