快捷搜索:  as  2018  FtCWSyGV  С˵  test  xxx  Ψһ  w3viyKQx

澳门新葡亰平台app:让.Net 应用程序突破2G的内存访问限制



本文示例源代码或素材下载

32位Windows操作系统下单个进程的用户模式内存造访的限定是2G,假如在boot.ini中设置了/3G开关,则最大年夜为3G,跨越3G将无法造访。因为Hubble.net 项目是一个数据库系统,必须要斟酌应用大年夜内存缓存数据的问题,于是近来对这个问题进行了一些钻研。着实这块的技巧是现成的,32位操作系统下只有经由过程AWE的要领来扩展内存。这块的文章也很多,但很少有.net 下若何应用的实例,我做了一个类似MemoryStream的封装,可以让.Net法度榜样员轻松操作AWE内存,从而使其法度榜样轻松冲破2G内存的限定。

在开始这篇文章之前,我们照样先来懂得一下AWE.

AWE (Address Windowing Extensions)是 Windows 的内存治理功能的一组扩展,它使利用法度榜样能够应用的内存量跨越经由过程标准 32 位寻址可应用的 2-3 GB 内存。AWE 容许利用法度榜样获取物理内存,然后将非分页内存的视图动态映射到 32 位地址空间。虽然 32 位地址空间限定为 4 GB,然则非分页内存却可以远弘远年夜于 4澳门新葡亰平台app GB。这使必要大年夜量内存的利用法度榜样(如大年夜型数据库系统)能应用的内存量远弘远年夜于 32 位地址空间所支持的内存量。

如上图所示AWE 实际上便是将用户模式下的32位内存地址映射到用户必要造访的物理内存上去。不合操作系统运行被映射的物理内存大年夜小是不一样的。

Vista, XP 和 Windows 2003 标准版 最多可以映射 4G 内存。

Windows 2003 企业版的限定是32G (要应用跨越4G的内存必须打开 /PAE 开关)

Windows 2003 数据中间版本限定是64G (要应用跨越4G的内存必须打开 /PAE 开关)

因为被映射的物理内存为不分页内存,无法进行页保护,为了包管内存应用的安然,防止其他进程越界造访,AWE 在映射这些内存之前必须将这些内存锁定,即只有锁定这块内存的进程可以造访这块内存,其它进程无法造访。这里就孕育发生了一个有趣的征象,我们可以在windows 下像实时操作系统那样操作物理内存,而不用担心操作系统进行页互换时对系统实时性的影响。虽然不采纳AWE,也可以经由过程VirtualLock API函数来锁定物理内存,但这个函数在一个进程中最多可以锁定30个页面,以一个页大年夜小4096来谋略,最多可以锁定30*4094字节的内存。当然这是默认设置,你也可以经由过程调剂事情 WorkingSet 来调剂。看来AWE对付那些实时性对照高的利用,比如游戏,动画,通讯等还确凿是一个福音。

因为必要锁定物理内存,以是运行AWE功能的法度榜样,必须要具备锁定内存的权限,系统治理员帐号是没有这个权限的,只有 System帐号有这个权限。当然你也可以在本地安然设置中指定某个帐号拥有这个权限。措施如下:

gpedit.msc ->Windows Settings->Security Settings->Local Policies->User Rights Assignment->Lock pages in memory

谈完锁定内存的问题,我们再看看上面那个图,我们会发明虽然AWE容许造访最多64G的内存,但这64G内存是被AWE映射到一个32位的用户模式下的内存地址中去的,也便是说平日环境下,我们最多可以同时造访64G内存中的2G内存 (假如设置设置设备澳门新葡亰平台app摆设摆设了/3G开关,可以同时造访最多16G内存中的3G内存),假如要造访全部64G的内存,我们必要将一些不造访的内存取消映射,这样可以空出足够的用户模式下的虚拟澳门新葡亰平台app内存地址来造访我们必要造访的内存。是以我封装的类中添加了Map和UnMap两个措施,让调用者可以根据实际环境来抉择映射和去映射。2G的32位虚拟内存地址对付我们来是是如斯的宝贵,调用者在贪婪的耗损大年夜量内存时必然要留意节约这个资本。

我在 6G内存 windows 2003 企业版的情况中做了测试,申请内存到5G以上没有任何问题。

下面再看看若何来申请AWE内存

下面的AweStream构造函数完成了对AWE内存的申请历程。

全部申请历程分为下面几步

1、为当提高程申请锁定内存的权限(留意 调用进程的帐号必须具备锁定内存的权限,否则这一步会掉败)

2、便是必要申请的页面数量

3、经由过程 AllocateUserPhysicalPages API 申请AWE内存

public AweStream(UInt32 capacity)

{

unsafe

{

// Enable the privilege of lock memory.

lock (_SetLockPagesPrivilegeLockObj)

{

if (!_SetLockPagesPrivilegeOk)

{

LoggedSetLockPagesPrivilege.SetLockPagesPrivilege(System.Diagnostics.Process.GetCurrentProcess(), true);

_SetLockPagesPrivilegeOk = true;

}

}

General.SYSTEM_INFO sysInfo;

General.GetSystemInfo(out sysInfo); // fill the system information structure

_PageSize = sysInfo.dwPageSize;

if ((capacity % _PageSize) != 0)

{

_NumberOfPages = capacity / _PageSize + 1;

}

else

{

_NumberOfPages = capacity / _PageSize;

}

_PFNArraySize = (UInt32)(_NumberOfPages * sizeof(UInt64*));        // mem澳门新葡亰平台appory to request for PFN array

_PFNArray = Marshal.AllocHGlobal((int)_PFNArraySize);

UInt32 numberOfPagesInitial = _NumberOfPages;

if (!AweApi.AllocateUserPhysicalPages(System.Diagnostics.Process.GetCurrentProcess().Handle,

ref _NumberOfPages, _PFNArr澳门新葡亰平台appay))

{

Dispose();

throw new AweStreamException("Cannot allocate physical pages", AweStreamException.Reason.CannotAllocatePhysicalPages);

}

_AweAllocated = true;

if (numberOfPagesInitial != _NumberOfPages)

{

Dispose();

throw new AweStreamException(string.Format("Allocated only {0} pages.", _NumberOfPages),

AweStreamException.Reason.AweMemoryNotEnough);

}

_Capacity = _PageSize * _NumberOfPages;

}

}

您可能还会对下面的文章感兴趣: