我正在使用我没有创建的第三方对象,随着时间的推移消耗了大量资源。该对象不应以任何方式包含状态,它只是执行计算。尽管如此,每次我调用此对象的特定函数时,都会消耗更多的内存。几个小时后,我的程序占用了几千兆字节的内存。
该对象在我的命令行应用程序中初始化为我的Program类的静态成员。我发现如果我将整个程序包装在一个类中,并且不时地重新初始化它,那么旧的(和膨胀的)对象将由GC取消分配,并且一个新的较小的对象将替换它。
我的问题是这种方法非常笨拙并且破坏了我的程序流程。
还有其他方法可以处理一个物体吗?我相信GC.Collect()只会处理无法访问的代码。无论如何我可以让一个物体'无法到达'吗?
修改:根据要求,代码:
static ILexicon lexicon = new Lexicon();
...
lexicon.LoadDataFromFile(@"lexicon.dat", null);
...
byte similarityScore(string w1, string w2, PartOfSpeech pos, SimilarityMeasure measure)
{
if (w1 == w2)
return 255;
if (pos != PartOfSpeech.Noun && pos != PartOfSpeech.Verb)
return 0;
IList<ILemma> w1_lemmas = lexicon.FindSenses(w1, pos);
IList<ILemma> w2_lemmas = lexicon.FindSenses(w2, pos);
byte result;
byte score = 0;
foreach (ILemma w1_lemma in w1_lemmas)
{
foreach (ILemma w2_lemma in w2_lemmas)
{
result = (byte) (w1_lemma.GetSimilarity(w2_lemma, measure) * 255);
if (result > score)
score = result;
}
}
return score;
}
调用similarityScore时,会为lexicon
的私有成员分配更多内存。它没有实现IDisposable,也没有明显的功能来清除内存。该库基于WordNet,并使用算法在上位词树中查找路径长度以计算两个单词的相似度。除非有缓存,否则我无法理解为什么需要存储任何内存。可以肯定的是,我无法改变它。我几乎可以肯定我的代码没有任何问题。当它变得太大时我只需要处理lexicon
(N.B.它需要一两秒才能将词典从文件加载到内存中)
答案 0 :(得分:1)
如果对象没有实现IDisposable并且您想将其推出作用域,则可以将对它的所有引用设置为null,然后使用GC.Collect()强制进行垃圾回收。
GC.Collect()非常昂贵。如果您不得不经常这样做,您可能需要考虑与供应商联系。
了解:
附加说明:如果第三方库是本机的,并且您必须使用互操作,则可以使用Marshal.ReleaseComObject释放非托管内存。
答案 1 :(得分:0)
您可以尝试调用Dispose()方法。这会使对象无法使用,因此您必须实例化另一个对象。我假设你的程序是循环的,所以它可以是一个循环变量,调用dispose在底部。
答案 2 :(得分:0)
我建议如果您可以使用内存分析器,就可以使用它。内存分析器将允许您暂停程序,单击一个类,然后查看该类的对象列表。然后,可以单击一个对象并查看它是如何创建的,以及从根开始到该对象的“路径”(例如,有一个静态类foo,它保存对一个条形的引用,它包含对boz的引用,提到了一个真正的大事。通常情况下,看到这一点就会明确需要做些什么才能打破链条。
答案 3 :(得分:0)
您可以从wordnet存储库下载源代码并修改代码,因为它是一个开源。