【问题标题】:Get maximum available heap memory获取最大可用堆内存
【发布时间】:2019-12-03 07:24:13
【问题描述】:

我目前正在尝试找出可以通过 C 中的 malloc() 命令分配的最大内存。 到目前为止,我已经尝试了一种简单的算法,该算法会增加随后将被分配的计数器。如果 malloc 命令返回“NULL”,我知道,没有足够的可用内存。

        ULONG ulMaxSize = 0;

        for (ULONG ulSize = /*0x40036FF0*/ 0x40A00000; ulSize <= 0xffffffff; ulSize++)
        {
            void* pBuffer = malloc(ulSize);
            if (pBuffer == NULL)
            {
                ulMaxSize = ulSize - 1;
                break;
            }
            free(pBuffer);
        }

        void* pMaxBuffer = malloc(ulMaxSize);

但是,由于 malloc() 命令被证明是一项耗时的任务,因此该算法执行时间很长。

我现在的问题是,是否有更有效的算法来找到能够分配的最大内存?

【问题讨论】:

  • 取决于操作系统,这可能会导致您的进程被杀死,或触发 OOM 管理器。虽然再次取决于您的操作系统,但您可能已经拥有用于获取此类数字的 API
  • 对于 linux 你可以看看sysinfo
  • 那么 Windows 平台各自的 API 是什么?
  • win32 等价于 GlobalMemoryStatusEx
  • 请注意,Linux 在其默认配置中启用了内存过量使用,将事实上向您的程序谎报可用内存量。如果你的进程胆敢实际使用请求的内存,你的进程很可能会被out-of-fuel, errr, out-of-memory killer 杀死。 (希望没有任何关键进程会受到whacked 的附带损害...)因此,没有真正的方法可以在默认 Linux 安装上获得最大内存分配。

标签: c malloc dynamic-memory-allocation


【解决方案1】:

可以分配的最大内存主要取决于几个因素:

  • 解决进程的空间限制(最大内存、虚拟内存和好友)。
  • 可用的虚拟空间
  • 可用物理空间
  • 分片,这将限制连续内存块的大小。
  • ...其他限制...

从您的描述(极其缓慢)看来,该进程开始使用交换,这与实际内存相比非常慢。

考虑以下替代方案

  • 有关地址空间限制,请查看ulimit -a(或使用 getrlimit 从 C 程序访问相同的数据) - 查找“最大内存大小”和“虚拟内存”
  • 对于交换空间,物理内存 - 顶部
ulimit -a (filtered)

data seg size           (kbytes, -d) unlimited
max memory size         (kbytes, -m) 2048
stack size              (kbytes, -s) 8192
virtual memory          (kbytes, -v) unlimited

从实际角度来看,鉴于程序无法控制系统资源,您应该关注“最大内存大小”。

【讨论】:

    【解决方案2】:

    除了使用操作系统特定的 API 来获取这样的数字:

    您也可以进行二分搜索,但不推荐,因为系统状态可能会不断变化,结果可能会随时间变化:

    ULONG getMax() {
        ULONG min = 0x0;
        ULONG max = 0xffffffff;
        void* t = malloc(max);
        if(t!=NULL) {
            free(t);
            return max;
        }
        while(max-min > 1) {
            ULONG mid = min + (max - min) / 2;
            t = malloc(mid);
            if(t == NULL) {
                max = mid;
                continue;
            }
            free(t);
            min = mid;
        }
        return min;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-06
      • 2011-05-20
      • 1970-01-01
      • 1970-01-01
      • 2016-01-29
      • 1970-01-01
      • 1970-01-01
      • 2017-08-12
      相关资源
      最近更新 更多