此代码是否会导致内存过度使用

本文关键字:内存 代码 是否 | 更新日期: 2023-09-27 18:00:54

我正在研究一些代码(由其他人编写(,以找出是什么导致内存使用量迅速增加到8GB。我不是一个真正的开发人员,更像是一个自学成才的业余爱好者,在工作中做一些编码,所以这有点让我不知所措。

下面的代码,特别是在每次迭代中为lin创建一个新对象,会导致内存快速增长吗?大约有300万条记录正在处理中。每一列中的数据都没有什么特别之处。

conn是一个自定义类。

SqlDataReader rdr = comm.ExecuteReader();
object[] lin = new object[17];
while (rdr.Read()){
    rdr.GetValues(lin);
    conn.Submit(lin, ref cmdString, ref recCount);
    lin = new object[17];
    }

我看到了一些与内存相关的问题的答案,这些问题是关于垃圾收集器无法跟上的。在我看来,在每次迭代中创建一个新对象是不必要的。

此代码是否会导致内存过度使用

这取决于可用内存的大小。由于循环体的最后一行覆盖了lin,所以似乎再也没有人引用它了。只有rdrconn是可疑的,因为他们可能会无缘无故地保留一个。如果没有,它将可用于垃圾收集,垃圾收集将负责在必要时释放初始化的数组的资源。

然而,一个更干净的解决方案可能是这样的,其中数组被清除并重用,而不是初始化一个新的数组并覆盖用于保存前一个数组的旧变量。

var lin = new object[17];
while (rdr.Read()){
    rdr.GetValues(lin);
    conn.Submit(lin, ref cmdString, ref recCount);
    Array.Clear(lin, 0, 17);
}

至少,您可以像我在评论中所说的那样,将数组声明移动到内部范围:

while (rdr.Read()){
    var lin = new object[17];
    rdr.GetValues(lin);
    conn.Submit(lin, ref cmdString, ref recCount);
}

我不确定哪种解决方案会更快,但我相信你可以通过反复试验来找出答案。

您不应该每次循环都创建一个新对象。rdr。GetValues(lin(将覆盖内存中的值,假设它填充了所有17个空格。

如果它没有清除空格,你至少需要清除17个空格,以确保你没有重复使用旧数据。

在Oppasum所说的更详细的内容中,我认为您的"lin"变量可能是罪魁祸首。

通过在每个循环中执行新的操作,可以分配内存,而不是重用它。在循环之外创建对象是正确的,因为这会重用对象内存。我不记得rdr。GetValues((要求传入的对象数组是否为空。它可能只是覆盖现有值,因此不需要清除。

SqlDataReader rdr = comm.ExecuteReader();
object[] lin = new object[17];
while (rdr.Read())
{
    rdr.GetValues(lin);
    conn.Submit(lin, ref cmdString, ref recCount);
    // Clearing, but may not be nessessary.
    for(int i; i<lin.Length;i++)
        lin[i] = null;
}

话虽如此,解决内存问题的最佳方法仍然是使用像RedGate这样的探查器。它有14天的免费试用期,所以你可以在购买之前弄清楚它是否对你有帮助。