Мы загружаем файл 222 МБ в MemoryMappedFile для доступа к необработанным данным. Эти данные обновляются с использованием метода write. После некоторых вычислений данные должны быть сброшены до исходного значения файла. В настоящее время мы делаем это, удаляя класс и создавая новый экземпляр. Это идет хорошо много раз, но иногда CreateViewAccessor падает со следующим исключением:MemoryMappedFile CreateViewAccessor выбрасывает «Недостаточно памяти для обработки этой команды».
System.Exception: Недостаточно памяти для обработки команды. ---> System.IO.IOException: для обработки этой команды недостаточно памяти.
на System.IO .__ Error.WinIOError (Int32 ERRORCODE, String maybeFullPath) в System.IO.MemoryMappedFiles.MemoryMappedView.CreateView (SafeMemoryMappedFileHandle> memMappedFileHandle, MemoryMappedFileAccess доступа, Int64 смещение, размер Int64) в System.IO. MemoryMappedFiles.MemoryMappedFile.CreateViewAccessor (Int64 смещение, Int64> размер, MemoryMappedFileAccess доступа)
следующий класс используется для доступа к memorymapped файла:
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));
}
}
Каковы возможные причины этой проблемы и есть ли какое-либо решение/обходное решение?
Вы пытались вызвать «GC.Collect» после утилизации MMF? эта ошибка обычно означает, что памяти недостаточно. –
Мы закончили тем, что создали собственный картограф, который загружает блоки этого файла в память, поэтому не нужно иметь один большой блок свободного пространства в памяти. Вы можете проверить это на https://gist.github.com/luuksommers/af473efe618d589df951 – Luuk