作为论文的一部分,我需要加载,修改和保存.dds纹理文件。因此我正在使用DevIL.NET-Wrapper库(但问题并不是特定于这个库我想,这更像是一个普遍问题)。
我管理(通过使用visual studio内存分析工具)来找出DevIL.NET-Wrapper中的内存泄漏函数:
public static byte[] ReadStreamFully(Stream stream, int initialLength) {
if(initialLength < 1) {
initialLength = 32768; //Init to 32K if not a valid initial length
}
byte[] buffer = new byte[initialLength];
int position = 0;
int chunk;
while((chunk = stream.Read(buffer, position, buffer.Length - position)) > 0) {
position += chunk;
//If we reached the end of the buffer check to see if there's more info
if(position == buffer.Length) {
int nextByte = stream.ReadByte();
//If -1 we reached the end of the stream
if(nextByte == -1) {
return buffer;
}
//Not at the end, need to resize the buffer
byte[] newBuffer = new byte[buffer.Length * 2];
Array.Copy(buffer, newBuffer, buffer.Length);
newBuffer[position] = (byte) nextByte;
buffer = newBuffer;
position++;
}
}
//Trim the buffer before returning
byte[] toReturn = new byte[position];
Array.Copy(buffer, toReturn, position);
return toReturn;
}
我做了一个测试程序来确定内存泄漏的实际来源:
private static void testMemoryOverflow(string[] args)
{
DevIL.ImageImporter im;
DevIL.ImageExporter ie;
...
foreach (String file in ddsPaths)
{
using (FileStream fs = File.Open(file, FileMode.Open))
{
/* v memory leak v */
DevIL.Image img = im.LoadImageFromStream(fs);
/* ^ memory leak ^ */
ie.SaveImage(img, fileSavePath);
img = null;
}
}
}
LoadImageFromStream()函数也是DevIL.NET-Wrapper的一部分,实际上是从上面调用函数。这是泄漏发生的地方。
我已经尝试过:
有人有解决方案吗? 我是C#的新手,所以也许这是一个基本的错误。
答案 0 :(得分:2)
您的问题是缓冲区大小。
byte[] newBuffer = new byte[buffer.Length * 2];
经过2次迭代..你已经非常接近撞击大对象堆的85K极限。在3次迭代......你已达到门槛。一旦那里......直到所有世代都发生了完整的垃圾收集,它们才会被收集。即便如此...... LOH还没有被压缩..所以你仍会看到一些高记忆。
我不确定您使用的库为何会这样做。我不确定你为什么要使用它......鉴于你可以使用:
Image img = Image.FromStream(fs); // built into .NET.
编写库的方式看起来像是早期版本的.NET。它似乎没有内存使用任何问题。