【问题标题】:Is there an equivalent of sbrk(0) on WindowsWindows 上是否有 sbrk(0) 的等价物
【发布时间】:2015-01-06 16:27:31
【问题描述】:

我使用 sbrk(0) 从应用程序中监控动态内存的使用情况。在我做的程序开始时

dynamic_base = sbrk(0);

以及通过程序使用的各个点

sbrk(0) - dynamic_base

作为当前内存使用高水位线的衡量标准。是否有适用于 Windows 的等价物?

或者,有没有更好的方法可以从 Windows 和 Unix 的进程中确定动态内存使用情况。

【问题讨论】:

标签: c windows memory-management


【解决方案1】:

IInspectable 建议的性能计数器可以工作,但它们有些复杂。

如果您只想知道应用程序正在使用的内存量,请调用GlobalMemoryStatusEx 并检查结果中的ullTotalVirtualullAvailVirtual 成员。

sbrk 方法不同,它不区分静态加载的代码和数据部分、动态加载的模块、线程堆栈和动态分配(堆)。但是这个数字的差异将是最大堆大小的差异。

【讨论】:

  • ullAvailVirtual 不包括未提交的保留内存。该内存基本上未被应用程序使用。由于 Visual Studio 附带的 CRT 的堆管理器从不将未提交的内存返回给操作系统,而是保留它,因此测量 ullAvailVirtual 将报告一个始终低于应用程序可用内存量的值。在实践中,它几乎没有什么用处,除了内存泄漏检测。
  • @IInspectable: 是的,但这仍然会占用虚拟地址空间......只有当应用程序使用 VirtualAlloc 来保留页面而不提交时,差异才会很大。在这方面,它的行为很像要求的sbrk
  • 这正是 CRT 所做的:它不会释放应用程序曾经请求过的任何内存,直到进程终止。当应用程序将内存返回给 CRT 的内存管理器时,它只会取消提交内存。内存将保持保留。因此,如果您对应用程序的内存压力感兴趣,ullAvailVirtual 数字通常不是一个好的衡量标准。
  • 我认为它也仍然提交,并添加到堆空闲列表中
  • 你是对的,默认的堆管理器不会取消提交内存,而是让它提交并在内部管理空闲区域。但效果保持不变:通过调用GlobalMemoryStatusEx 报告为已用 的内存包括从堆管理器的角度来看的空闲 内存。 ullAvailVirtual 不会考虑堆管理器的内部状态,通常不会回答应用程序使用多少内存的问题。
【解决方案2】:

sbrk 已过时,即使在 Linux 上也是如此(例如,因为对多线程不友好)。几个 malloc 实现只使用mmap(2)(而且它们中的大多数有时使用mmap,至少对于足够大的malloc-s)。

有没有更好的方法在 Linux 上从进程中确定动态内存使用情况?

(我跳过了问题的 Windows 部分)

在 Linux 上,您可以(而且您会更好)使用 proc(5) 来查询您的内存使用情况。特别是读取(这些是顺序的伪文件,有点像管道)/proc/self/stat/proc/self/maps/proc/self/statm 等。例如,fopen 它们、fscanf 它们、fclose 它们快速。不涉及真正的磁盘 IO,因为这些伪文件的内容由内核按需合成。

还有mallinfo(3)malloc_stats(3),至少对于malloc 在Linux 上的一些 实现。

【讨论】:

  • 好的,sbrk 已经过时了。所以你在 Windows 上做 mmap() 吗?它是否还有一个名为“mmap”的系统调用?
  • 我从未使用过 Windows。我不知道它是否有mmap(可能不是本地的)。也许最新的“Windows10 上的 bash/ubuntu”可能是一种 Linux 个性,提供了一些 Linux 系统调用的仿真,我真的不知道。
【解决方案3】:

VirtualAlloc 是 Windows 中的粗略等价物。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-17
    • 2019-11-08
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 2010-09-24
    • 1970-01-01
    相关资源
    最近更新 更多