gpt4 book ai didi

c# - MemoryMappedFile CreateViewAccessor 抛出 "Not enough storage is available to process this command."

转载 作者:太空狗 更新时间:2023-10-30 01:06:22 27 4
gpt4 key购买 nike

我们正在 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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com