我现在正在编写一个 Windows Store App Reader,用于使用 C# 查看 PDF 文件。
目前,我正在尝试解决可能导致内存泄漏的问题。在应用程序中,有一种加密和解密PDF文件的方法,加密/解密方法是自定义方法,PDF文件大小在1MB到120MB之间。
在加解密过程中,必须将文件以字节数组的形式读入内存,并对字节进行加解密处理。从方法返回后,字节数组超出范围。但似乎因为它是一个大字节数组(> 85k),我认为它是在大对象堆(LOH)中声明的,并且在收集垃圾之后,看起来 LOH 变得碎片化。
并且在应用打开、查看和切换更多 PDF 文件后,内存使用率越来越高,并且在某些时候会出现内存不足的异常。
有没有办法解决大字节数组问题?或者有人遇到过这样的问题吗?
我找到了 Memory Mapped Files 类,但它不能在 Windows Store App 中使用。
我也尝试过使用字节数组块(<85k)并逐部分处理文件,但在查看 PDF 之前加密和解密需要很长时间。
下面是代码片段:
public static async Task CryptoFile(StorageFolder Folder, string FileName, bool IsReaderFile)
{
...
...
byte[] fileContent = null;
buffer = await FileIO.ReadBufferAsync(file);
using (DataReader dataReader = DataReader.FromBuffer(buffer))
{
fileContent = new byte[dataReader.UnconsumedBufferLength];
dataReader.ReadBytes(fileContent);
}
if (fileContent == null)
CryptResult = false;
else if (fileContent.Length == 0)
CryptResult = false;
if (CryptResult)
{
//Encrypt/decrypt file
fileContent = await RecodeFile(fileContent, CryptKey, IsReaderFile);
//Delete the original file
file = await Folder.GetFileAsync(FileName);
await file.DeleteAsync(StorageDeleteOption.PermanentDelete);
//Recreate file
file = await Folder.CreateFileAsync(FileName);
using (IRandomAccessStream fs = await file.OpenAsync(FileAccessMode.ReadWrite))
{
using (IOutputStream outStream = fs.GetOutputStreamAt(0))
{
using (DataWriter dataWriter = new DataWriter(outStream))
{
dataWriter.WriteBytes(fileContent);
await dataWriter.StoreAsync();
dataWriter.DetachStream();
}
await outStream.FlushAsync();
}
}
....
}
}
fileContent 是用于读取整个文件内容的字节数组,从该方法返回时它将超出范围,我认为 fileContent 会导致内存碎片,因为它可能在 LOH 中声明它的大小。