- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我们正在 MemoryMappedFile 中加载一个 222MB 的文件以进行原始数据访问。此数据使用 write 方法更新。经过一些计算,数据应该被重置为文件的原始值。我们目前正在通过处理该类并创建一个新实例来做到这一点。这在很多时候都很顺利,但有时 CreateViewAccessor 会崩溃并出现以下异常:
System.Exception: Not enough storage is available to process this command. ---> System.IO.IOException: Not enough storage is available to process this command.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.IO.MemoryMappedFiles.MemoryMappedView.CreateView(SafeMemoryMappedFileHandle > memMappedFileHandle, MemoryMappedFileAccess access, Int64 offset, Int64 size) at System.IO.MemoryMappedFiles.MemoryMappedFile.CreateViewAccessor(Int64 offset, Int64 > size, MemoryMappedFileAccess access)
下面的类用于访问内存映射文件:
public unsafe class MemoryMapAccessor : IDisposable
{
private MemoryMappedViewAccessor _bmaccessor;
private MemoryMappedFile _mmf;
private byte* _ptr;
private long _size;
public MemoryMapAccessor(string path, string mapName)
{
FileInfo info = new FileInfo(path);
_size = info.Length;
using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite))
_mmf = MemoryMappedFile.CreateFromFile(stream, mapName, _size, MemoryMappedFileAccess.Read, null, HandleInheritability.None, false);
_bmaccessor = _mmf.CreateViewAccessor(0, 0, MemoryMappedFileAccess.CopyOnWrite);
_bmaccessor.SafeMemoryMappedViewHandle.AcquirePointer(ref _ptr);
}
public void Dispose()
{
if (_bmaccessor != null)
{
_bmaccessor.SafeMemoryMappedViewHandle.ReleasePointer();
_bmaccessor.Dispose();
}
if (_mmf != null)
_mmf.Dispose();
}
public long Size { get { return _size; } }
public byte ReadByte(long idx)
{
if ((idx >= 0) && (idx < _size))
{
return *(_ptr + idx);
}
Debug.Fail(string.Format("MemoryMapAccessor: Index out of range {0}", idx));
return 0;
}
public void Write(long position, byte value)
{
if ((position >= 0) && (position < _size))
{
*(_ptr + position) = value;
}
else
throw new Exception(string.Format("MemoryMapAccessor: Index out of range {0}", position));
}
}
此问题的可能原因是什么?是否有任何解决方案/变通方法?
最佳答案
尝试使用 x64 平台和进程代替 x32 平台
确保每次都手动处理 MemoryMapAccessor。根据您的实现,GC 将不会为您调用 Dispose - 这里有很好的解释 Proper use of the IDisposable interface
调用 Dispose 不会使您的变量为空,因此 GC 将等待直到它理解没有人使用这些变量。确保您的变量在 Dispose 之后超出范围,或者简单地将它们标记为 null。最简单的情况是在您的 Dispose 中进行处理——如果您不再需要变量,为什么不将它们标记为 null 呢?这让 GC 可以更快地吃掉它们。
这是另一个关于此类错误的好话题(虽然是指 VS.Net IDE,但它包含了可能发生此类错误的详细信息)Not enough storage is available to process this command in VisualStudio 2008如果您经常需要非常大的内存部分,这会导致内存碎片,那么您的想法之一就是当您仍然有足够的总可用内存时,您没有足够大的可用内存块。
对于您的具体情况,也许将 byte[]
数组从文件读取到内存中是一个不错的主意,但不会深入涉及非托管资源。通过一些幸运的编码,它可能会导致 CLR 更好地管理内存;但您需要谨慎做出此类决定。
关于c# - MemoryMappedFile CreateViewAccessor 抛出 "Not enough storage is available to process this command.",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15662455/
我是一名优秀的程序员,十分优秀!