让.Net 应用程序突破2G的内存访问限制
2008-11-06 14:00
344 查看
让.Net 应用程序突破2G的内存访问限制
Author: Eaglet
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 GB。这使需要大量内存的应用程序(如大型数据库系统)能使用的内存量远远大于 32 位地址空间所支持的内存量。
byte[] inputBuffer = new byte[1024];
Stopwatch stopWatch = new Stopwatch();
using (AweStream.AweStream aweStream = new AweStream.AweStream(1024 * 1024 * 100))
我在 6G内存 windows 2003 企业版的环境中做了测试,申请内存到5G以上没有任何问题。
下面再看看如何来申请AWE内存
下面的AweStream构造函数完成了对AWE内存的申请过程。
整个申请过程分为下面几步
1、为当前进程申请锁定内存的权限(注意 调用进程的帐号必须具备锁定内存的权限,否则这一步会失败)
2、就是需要申请的页面数量
3、通过 AllocateUserPhysicalPages API 申请AWE内存
public AweStream(UInt32 capacity)
AWE内存申请完毕后并不能被立即访问到,我们必须将其映射到32位内存地址中才可以访问。
下面是内存映射的代码:
也很简单:
首先先通过VirtualAlloc函数申请一块32位虚拟内存区域
然后通过 MapUserPhysicalPages API 函数将AWE内存映射到这个虚拟内存地址区域。
public void Map(bool readOnly)
{
unsafe
{
if (IsMapped)
{
return;
}
if (readOnly)
{
_VirtualAddress = AweApi.VirtualAlloc(null, Capacity, AweApi.MEM_RESERVE | AweApi.MEM_PHYSICAL,
AweApi.PAGE_READONLY);
}
else
{
_VirtualAddress = AweApi.VirtualAlloc(null, Capacity, AweApi.MEM_RESERVE | AweApi.MEM_PHYSICAL,
AweApi.PAGE_READWRITE);
}
if (_VirtualAddress == null)
{
throw new AweStreamException("Cannot reserve memory.", AweStreamException.Reason.CannotReserveMemory);
}
if (!AweApi.MapUserPhysicalPages(_VirtualAddress, _NumberOfPages, _PFNArray))
{
AweApi.VirtualFree(_VirtualAddress, Capacity, AweApi.MEM_RELEASE);
_VirtualAddress = null;
throw new AweStreamException(string.Format("MapUserPhysicalPages failed ({0})", General.GetLastError()),
AweStreamException.Reason.MapUserPhysicalPagesFail);
}
_CanWrite = !readOnly;
}
}
去映射和归还AWE内存的过程是上面两个过程的逆过程,这里就不再多讲,有兴趣可以看我的代码。
下面是实例代码下载位置
源代码地址
Author: Eaglet
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 GB。这使需要大量内存的应用程序(如大型数据库系统)能使用的内存量远远大于 32 位地址空间所支持的内存量。
byte[] inputBuffer = new byte[1024];
Stopwatch stopWatch = new Stopwatch();
using (AweStream.AweStream aweStream = new AweStream.AweStream(1024 * 1024 * 100))
我在 6G内存 windows 2003 企业版的环境中做了测试,申请内存到5G以上没有任何问题。
下面再看看如何来申请AWE内存
下面的AweStream构造函数完成了对AWE内存的申请过程。
整个申请过程分为下面几步
1、为当前进程申请锁定内存的权限(注意 调用进程的帐号必须具备锁定内存的权限,否则这一步会失败)
2、就是需要申请的页面数量
3、通过 AllocateUserPhysicalPages API 申请AWE内存
public AweStream(UInt32 capacity)
AWE内存申请完毕后并不能被立即访问到,我们必须将其映射到32位内存地址中才可以访问。
下面是内存映射的代码:
也很简单:
首先先通过VirtualAlloc函数申请一块32位虚拟内存区域
然后通过 MapUserPhysicalPages API 函数将AWE内存映射到这个虚拟内存地址区域。
public void Map(bool readOnly)
{
unsafe
{
if (IsMapped)
{
return;
}
if (readOnly)
{
_VirtualAddress = AweApi.VirtualAlloc(null, Capacity, AweApi.MEM_RESERVE | AweApi.MEM_PHYSICAL,
AweApi.PAGE_READONLY);
}
else
{
_VirtualAddress = AweApi.VirtualAlloc(null, Capacity, AweApi.MEM_RESERVE | AweApi.MEM_PHYSICAL,
AweApi.PAGE_READWRITE);
}
if (_VirtualAddress == null)
{
throw new AweStreamException("Cannot reserve memory.", AweStreamException.Reason.CannotReserveMemory);
}
if (!AweApi.MapUserPhysicalPages(_VirtualAddress, _NumberOfPages, _PFNArray))
{
AweApi.VirtualFree(_VirtualAddress, Capacity, AweApi.MEM_RELEASE);
_VirtualAddress = null;
throw new AweStreamException(string.Format("MapUserPhysicalPages failed ({0})", General.GetLastError()),
AweStreamException.Reason.MapUserPhysicalPagesFail);
}
_CanWrite = !readOnly;
}
}
去映射和归还AWE内存的过程是上面两个过程的逆过程,这里就不再多讲,有兴趣可以看我的代码。
下面是实例代码下载位置
源代码地址
相关文章推荐
- 让.Net 应用程序突破2G的内存访问限制
- 【c#】让.Net 应用程序突破2G的内存访问限制
- 让.Net 应用程序突破2G的内存访问限制
- 让.Net 应用程序突破2G的内存访问限制
- 让.Net 应用程序突破2G的内存访问限制
- 让.Net 应用程序突破2G的内存访问限制
- 让.Net 应用程序突破2G的内存访问限制
- 让.Net 应用程序突破2G的内存访问限制64G
- .Net 应用程序突破2G的内存访问限制
- [转]突破oracle for win2K的2G内存限制
- 让32位应用程序不再为2G内存限制苦恼
- 让SQL SERVER突破2G内存限制
- 突破2G内存限制 SQL2005 AWE应用测试
- 让SQL SERVER突破2G内存限制
- 在32位windos server 2003上让进程突破2G内存的限制
- 如何解决在Xp系统中应用程序有2G内存的限制
- 突破oracle for win2K的2G内存限制
- 突破Android Java应用程序的内存限制
- 突破2G内存限制 SQL2005 AWE应用测试
- 突破oracle for win2K 的2G内存限制 (转载自IT_PUB)