【问题标题】:How to obtain a current page size of the memory MS Windows 7 in C#?如何在 C# 中获取内存 MS Windows 7 的当前页面大小?
【发布时间】:2011-12-12 14:49:31
【问题描述】:

如何在C#中获取MS Windows 7内存的当前页面大小?

在某些情况下,我们需要它以最佳方式分配内存。

谢谢!

更新:这是一个示例代码...我对byte[] buffer = new byte[4096];这一行有一些疑问

// Assign values to these objects here so that they can
// be referenced in the finally block
Stream remoteStream = null;
Stream localStream = null;
WebResponse response = null;

try
{
    response = request.EndGetResponse(result);

    if (response != null)
    {
        // Once the WebResponse object has been retrieved, get the stream object associated with the response's data
        remoteStream = response.GetResponseStream();

        // Create the local file
        string pathToSaveFile = Path.Combine(FileManager.GetFolderContent(), TaskResult.ContentItem.FileName);
        localStream = File.Create(pathToSaveFile);

        // Allocate a 1k buffer http://en.wikipedia.org/wiki/Page_(computer_memory)
        byte[] buffer = new byte[4096];      
        int bytesRead;

        // Simple do/while loop to read from stream until no bytes are returned
        do
        {
            // Read data (up to 1k) from the stream
            bytesRead = remoteStream.Read(buffer, 0, buffer.Length);

【问题讨论】:

  • 真的确定知道页面大小可以让您在如何分配内存方面做出更好的选择吗?如果是这样,您确定 C# 是开发您的解决方案的最佳技术吗?您介意发布一个示例,说明知道页面大小有助于您分配内存吗?
  • 请看我的示例代码。正如你在这里看到的 byte[] buffer = new byte[4096]; 4096 是硬编码的。我需要在这里使用正确的值,例如在 MS Windows 7 x86 和 x64 的情况下

标签: c# .net memory memory-management


【解决方案1】:

如果您使用的是 C# 4.0,则属性 Environment.SystemPageSize 在内部使用 GetSystemInfo。因为是新的所以没见过。

http://msdn.microsoft.com/en-us/library/system.environment.systempagesize.aspx

在 C 中你可以写出这样的东西。

#include <windows.h>
int main(void) {
    SYSTEM_INFO si;
    GetSystemInfo(&si);

    printf("The page size for this system is %u bytes.\n", si.dwPageSize);

    return 0;
}

然后,您可以使用 P/INVOKE 调用 GetSystemInfo。 看看http://www.pinvoke.net/default.aspx/kernel32.getsysteminfo

我还必须补充一点,分配页面大小的字节数组不是最佳选择。

首先,C#内存可以移动,C#使用了一个compacting generational垃圾收集器。 没有任何关于数据分配位置的信息。

其次,C#中的数组可以由不连续的内存区域组成!数组是连续存储在虚拟内存中的,但是连续的虚拟内存不是连续的物理内存。

第三,C#中的数组数据结构比内容本身多占用一些字节(它存储数组大小和其他信息)。如果您分配页面大小的字节数,使用数组几乎总是会切换页面!

我认为这种优化可以是非优化。

通常 C# 数组的性能非常好,无需使用页面大小来分割内存。

如果您确实需要精确分配数据,则需要使用固定数组或 Marshal 分配,但这会减慢垃圾收集器的速度。

我会说最好只使用数组而不考虑页面大小。

【讨论】:

    【解决方案2】:

    使用 pinvoke 调用 GetSystemInfo() 并使用 dwPageSize 值。虽然你可能真的想要 dwAllocationGranularity,这是VirtualAlloc() 将分配的最小块。

    【讨论】:

    • 谢谢大家!这正是我要求的! pinvoke.net/default.aspx/kernel32.getsysteminfo 所以现在我可以这样做了... WinApi.SYSTEM_INFO sysinfo = new WinApi.SYSTEM_INFO(); WinApi.GetSystemInfo(ref sysinfo); // 分配一个缓冲区 byte[] buffer = new byte[int.Parse(sysinfo.dwPageSize.ToString())];
    猜你喜欢
    • 1970-01-01
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    • 2019-09-24
    • 2020-06-27
    • 2010-10-10
    • 2011-12-11
    • 1970-01-01
    相关资源
    最近更新 更多