封装:内存镜像文件(MemoryMappedFile)封装,一维二维三维定点访问

本文主要是介绍封装:内存镜像文件(MemoryMappedFile)封装,一维二维三维定点访问,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

MemoryMappedFile简介:



1、问题:公司底层限制使用32位应用程序,针对大数据数据模型会产生内存溢出;

2、解决方案:C#中可以使用MemoryMappedFile类将内存映射到硬盘中,将大网格数据保存在硬盘中节省内存;


3、实测结果:读取写入速度可以接受,持久化效果良好;

4、针对使用结构进行了如下封装,可用于泛型索引访问

    /// <summary> 泛型 T 内存映射文件 </summary>public partial class MmfEntity<T> where T : struct{#region - 成员变量 -private long _size;/// <summary> 文件大小 </summary>public long Size{get { return _size; }}/// <summary> 实体大小 </summary>public int MLeight{get { return Marshal.SizeOf(typeof(T)); }}private int _count;/// <summary> T 类型的数量 </summary>public int Count{get { return _count; }set{//  设置容器大小this._size = MLeight * value;_count = value;}}private string _file;/// <summary> 文件全路径 </summary>public string FileInf{get { return _file; }set { _file = value; }}private string _name;/// <summary> 镜像名称 </summary>public string Name{get{if (string.IsNullOrEmpty(_name)){_name = Path.GetFileNameWithoutExtension(_file);}return _name;}}private MemoryMappedFile _mmf;/// <summary> 内存镜像 </summary>protected MemoryMappedFile Mmf{get{BuildFile();return _mmf;}}/// <summary> 创建文件 </summary>void BuildFile(){if (File.Exists(this.FileInf)){this.Dispose();File.Delete(this.FileInf);}//  如果存在删除_mmf = MemoryMappedFile.CreateFromFile(this.FileInf, FileMode.OpenOrCreate, _name, _size, MemoryMappedFileAccess.ReadWriteExecute);}private MemoryMappedViewAccessor _mapView;/// <summary> 随机访问视图  </summary>protected MemoryMappedViewAccessor MapView{get{if (_mmf == null){this.BuildFile();}if (_mapView == null){_mapView = _mmf.CreateViewAccessor();}return _mapView;}}private MemoryMappedViewStream _mapStream;/// <summary> 按循序访问的流 </summary>protected MemoryMappedViewStream MapStream{get{if (_mmf == null){this.BuildFile();}if (_mapStream == null){_mapStream = _mmf.CreateViewStream();}return _mapStream;}private set { _mapStream = value; }}#endregion/// <summary> 将 T 类型的结构从访问器读取到提供的引用中 </summary>public T GetPostion(long position){T structure;MapView.Read<T>(position, out structure);return structure;}/// <summary> 读取指定索引处结构 </summary>public T GetIndex(int index){long postion = index * this.MLeight;return this.GetPostion(postion);}/// <summary> 将 T 类型的结构从访问器读取到 T 类型的数组中 </summary>public T[] GetPostion(int count, long position = 0){T[] arr = new T[count];MapView.ReadArray<T>(position, arr, 0, count);return arr;}/// <summary> 将 T 类型的结构从访问器读取到 T 类型的数组中 </summary>public T[] GetAll(long position = 0){T[] arr = new T[this._count];MapView.ReadArray<T>(position, arr, 0, this._count);return arr;}/// <summary> 将一个结构写入访问器 </summary>public void SetPosition(long position, T structure){MapView.Write<T>(position, ref structure);}/// <summary> 写入指定索引处结构 </summary>public void SetIndex(int index, T structure){long postion = index * this.MLeight;this.SetPosition(postion, structure);}/// <summary> 将结构从 T 类型的数组写入访问器 </summary>public void SetPosition(long position, T[] arr){MapView.WriteArray<T>(position, arr, 0, arr.Length);}/// <summary> 将结构从 T 类型的数组写入访问器 </summary>public void SetAll(T[] arr){MapView.WriteArray<T>(0, arr, 0, arr.Length);}/// <summary> 将结构从 T 类型的数组写入访问器 </summary>public void SetAll(T t){T[] arr = new T[this.Count];this.Count.DoCountWhile(l => arr[l] = t);MapView.WriteArray<T>(0, arr, 0, this.Count);}/// <summary> 重置大小 </summary>public void ReSetSize(int count){this._count = count;this._size = count * this.MLeight;this.BuildFile();}}partial class MmfEntity<T> : IDisposable{#region - 构造函数 -public MmfEntity(string fileFullPath, int Tcount){this._file = fileFullPath;this._count = Tcount;this._size = Tcount * this.MLeight;this._name = Path.GetFileNameWithoutExtension(fileFullPath);this.BuildFile();}#endregion#region - 资源释放 -private bool _isDisposed = false;~MmfEntity(){Dispose(false);}public void Dispose(){Dispose(true);GC.SuppressFinalize(this);}protected virtual void Dispose(bool disposing){if (!_isDisposed){if (disposing){if (this._mapView != null) this._mapView.Dispose();if (this._mmf != null) this._mmf.Dispose();}this._isDisposed = true;}}#endregion}

5、针对二维三维的定点结构访问

    /// <summary> 二维存储结构 </summary>public class DxyMmfEntity<T> : MmfEntity<T> where T : struct{#region - 构造函数 -public DxyMmfEntity(string fileFullPath, int Tcount): base(fileFullPath, Tcount){}#endregionprivate int _x;/// <summary> X维数 </summary>public int X{get { return _x; }set { _x = value; }}private int _y;/// <summary> Y维数 </summary>public int Y{get { return _y; }set { _y = value; }}public void Set(int x, int y, T value) {this.SetIndex(TranFucntion(x, y), value);}/// <summary> 获取指定二维值 </summary>public T Get(int x, int y){return this.GetIndex(TranFucntion(x, y));}Func<int, int, int> tranFucntion;/// <summary> 设置指定二维值 </summary>public Func<int, int, int> TranFucntion{get { return (x, y) => y * this.X + x; }}}


    /// <summary> 三维存储结构 </summary>public class DxyzMmfEntity<T> : MmfEntity<T> where T : struct{#region - 构造函数 -public DxyzMmfEntity(string fileFullPath, int x, int y, int z): base(fileFullPath, x * y * z){this.X = x;this.Y = y;this.Z = z;}/// <summary> 初始化方法 </summary>public void Init(int x, int y, int z){this.X = x;this.Y = y;this.Z = z;base.ReSetSize(x * y * z);}#endregionprivate int _x;/// <summary> X维数 </summary>public int X{get { return _x; }set { _x = value; }}private int _y;/// <summary> Y维数 </summary>public int Y{get { return _y; }set { _y = value; }}private int _z;/// <summary> Z方向维数 </summary>public int Z{get { return _z; }set { _z = value; }}public void Set(int x, int y, int z, T value){this.SetIndex(TranFucntion(x, y, z), value);}/// <summary> 获取指定二维值 </summary>public T Get(int x, int y, int z){return this.GetIndex(TranFucntion(x, y, z));}Func<int, int, int> tranFucntion;/// <summary> 设置指定二维值 </summary>public Func<int, int, int, int> TranFucntion{get { return (x, y, z) => z * this.X * this.Y + y * this.X + x; }}}

6,测试用例

 class Program{static void Main(string[] args){long offset = 0x10000000; // 256 megabyteslong length = 0x20000000; // 512 megabyteslong test = 800 * 1024;// 800 * 1024 * 1024;// 800MBDateTime time = DateTime.Now;Console.WriteLine("开始创建文件!");using (MmfEntity<int> mmf = new MmfEntity<int>(@"E:\ExtremelyLargeImage.data", 100)){for (int i = 0; i < 100; i++){mmf.SetIndex(i, i);}for (int i = 0; i < 100; i++){Console.WriteLine("执行:" + i + "  值:" + mmf.GetIndex(i));}
            }
           Console.WriteLine("完成!");Console.WriteLine("大小:" + test + "用时:" + (DateTime.Now - time).ToString());Console.Read();}
}

7、MemoryMappedFile结构图



这篇关于封装:内存镜像文件(MemoryMappedFile)封装,一维二维三维定点访问的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1005049

相关文章

深入理解Go语言中二维切片的使用

《深入理解Go语言中二维切片的使用》本文深入讲解了Go语言中二维切片的概念与应用,用于表示矩阵、表格等二维数据结构,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录引言二维切片的基本概念定义创建二维切片二维切片的操作访问元素修改元素遍历二维切片二维切片的动态调整追加行动态

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Java内存分配与JVM参数详解(推荐)

《Java内存分配与JVM参数详解(推荐)》本文详解JVM内存结构与参数调整,涵盖堆分代、元空间、GC选择及优化策略,帮助开发者提升性能、避免内存泄漏,本文给大家介绍Java内存分配与JVM参数详解,... 目录引言JVM内存结构JVM参数概述堆内存分配年轻代与老年代调整堆内存大小调整年轻代与老年代比例元空

MySQL中的InnoDB单表访问过程

《MySQL中的InnoDB单表访问过程》:本文主要介绍MySQL中的InnoDB单表访问过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、访问类型【1】const【2】ref【3】ref_or_null【4】range【5】index【6】

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

前端如何通过nginx访问本地端口

《前端如何通过nginx访问本地端口》:本文主要介绍前端如何通过nginx访问本地端口的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、nginx安装1、下载(1)下载地址(2)系统选择(3)版本选择2、安装部署(1)解压(2)配置文件修改(3)启动(4)

Python中对FFmpeg封装开发库FFmpy详解

《Python中对FFmpeg封装开发库FFmpy详解》:本文主要介绍Python中对FFmpeg封装开发库FFmpy,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、FFmpy简介与安装1.1 FFmpy概述1.2 安装方法二、FFmpy核心类与方法2.1 FF

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

Redis过期删除机制与内存淘汰策略的解析指南

《Redis过期删除机制与内存淘汰策略的解析指南》在使用Redis构建缓存系统时,很多开发者只设置了EXPIRE但却忽略了背后Redis的过期删除机制与内存淘汰策略,下面小编就来和大家详细介绍一下... 目录1、简述2、Redis http://www.chinasem.cn的过期删除策略(Key Expir

如何搭建并配置HTTPD文件服务及访问权限控制

《如何搭建并配置HTTPD文件服务及访问权限控制》:本文主要介绍如何搭建并配置HTTPD文件服务及访问权限控制的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、安装HTTPD服务二、HTTPD服务目录结构三、配置修改四、服务启动五、基于用户访问权限控制六、