【发布时间】:2011-12-02 04:25:51
【问题描述】:
我想创建一个工具来模拟内存限制以对其他应用程序进行内存压力测试。经过一些谷歌搜索后,我想出了以下代码,但是在运行此代码时,任务管理器或资源监视器不会显示内存使用量的任何差异。只是一条平线。
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Win32Tute
{
unsafe class Program
{
// Heap API flags
const int HEAP_ZERO_MEMORY = 0x00000008;
// Heap API functions
[DllImport("kernel32")]
static extern int GetProcessHeap();
[DllImport("kernel32")]
static extern void* HeapAlloc(int hHeap, int flags, int size);
[DllImport("kernel32")]
static extern bool HeapFree(int hHeap, int flags, void* block);
private static int ph = GetProcessHeap();
public static void* Alloc(int size)
{
void* result = HeapAlloc(ph, HEAP_ZERO_MEMORY, size);
if(result == null) throw new OutOfMemoryException("Couldn't execute HeapAlloc");
return result;
}
public static void Free(void* block)
{
if(!HeapFree(ph, 0, block)) throw new InvalidOperationException("Couldn't free memory");
}
public static void Main(string[] args)
{
int blockSize = 1024*1024; //1mb
byte*[] handles = new byte*[1024];
Console.WriteLine("Memory before : " + (Process.GetCurrentProcess().PrivateMemorySize64/1024)/1024); // get value in Megabytes
try
{
for(int i=0; i<1024; i++)
{
handles[i] = (byte*)Alloc(blockSize);
}
}
finally
{
Console.WriteLine("Memory after : " + (Process.GetCurrentProcess().PrivateMemorySize64 / 1024)/1024);
Console.WriteLine("Finished allocating 1024MB memory....Press Enter to free up.");
Console.ReadLine();
}
try
{
for(int i=0; i<1024; i++)
{
Free(handles[i]);
}
}
finally
{
Console.WriteLine("Memory at the end : " + (Process.GetCurrentProcess().PrivateMemorySize64 / 1024)/1024);
Console.WriteLine("All allocated memory freed. Press Enter to quit..");
Console.ReadLine();
}
}
}
}
【问题讨论】:
-
我试过你的代码,HeapAlloc 正在页面文件上分配内存,而在物理内存上没有。在 Resource Monitor 中,Commit KB 变为 ~1GB,如果您看到 Process.PagedMemorySize64 属性,它也显示 ~1GB。所以问题是如何强制 HeapAlloc 在物理内存上分配内存,而不是页面文件。
-
我尝试了 Marshal 类和 AllocHGlobal 的差异代码。起初它也给出了相同的结果。图表没有变化。然后我在 AllocHGlobal 之后调用了 Marshal.Copy()。然后只有内存分配反映在监视器中。所以我猜只是分配并不会真正从物理内存中保留空间。
-
我是内存管理新手。所以我不得不盲目地尝试一切。 :)
-
为什么不只是
var foo = new byte[100000000];(x10)? -
您可以尝试将一些数据写入您正在分配的内存。如果您不使用地址空间,它可能永远不必将其交换到物理内存中。您可能还想查看 VirtualLock 函数。您可以使用它将进程的虚拟地址空间锁定到物理内存中。
标签: c# memory-management stress-testing