当使用深度复制时,c#中的内存泄漏
本文关键字:内存 泄漏 深度 复制 | 更新日期: 2023-09-27 17:54:29
我正在做一个进化算法,我有一些内存泄漏的问题。基本上我有一个由树组成的种群。当我在两棵树之间进行交叉操作时,我想在两棵树之间交换两个子树。问题是这个进程泄漏了大量内存,导致我的程序在30-40代以上都是无用的。最重要的代码如下:
节点的类:
[System.Serializable]
public class TreeNode
{
ArrayList mChildren = new ArrayList();
TreeNode mParent;
public static TreeNode DeepClone<TreeNode>(TreeNode obj)
{
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
return (TreeNode) formatter.Deserialize(ms);
}
}
public TreeNode (TreeNode parent)
{
mParent = parent;
}
}
树的类:
[System.Serializable]
public class Tree
{
TreeNode mRoot = new TreeNode(null);
public static Tree DeepClone<Tree>(Tree obj)
{
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
return (Tree) formatter.Deserialize(ms);
}
}
}
我一直在看如何在。net(特别是c#)中对对象进行深度复制?用于深度复制,但我不确定它是否实现正确。
对于我的测试程序:
for (int i = 0; i < 50; i++)
{
trees[i] = new Tree();
trees[i].generateTree(30);
}
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 49; j++)
{
trees[j].getRandomSubtree(Tree.DeepClone<Tree>(trees[j+1]));
}
System.GC.Collect();
}
getRandomSubtree()函数基本上是从一棵树中随机选择一颗子树,并将其与另一棵树中随机选择的一颗子树交换。我还确保更新了子树的父引用。当我运行这段代码时,我的程序泄漏了大量内存。如果我停止深度拷贝,程序就会停止内存泄漏,所以我不太明白发生了什么。
我不认为你想要序列化父字段。标记为NonSerialized
。当然,您需要在反序列化之后修复这个问题。
或者在序列化之前将其设置为null
:
public static TreeNode DeepClone<TreeNode>(TreeNode obj)
{
TreeNode oldParent = obj.mParent;
obj.mParent = null;
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
obj.mParent = oldParent;
ms.Position = 0;
TreeNode result = (TreeNode) formatter.Deserialize(ms);
result.mParent = oldParent;
return result;
}
}