我在 Mac 上有 C++ 代码,看起来像这样:
Object* objectArray = new Object[1000];
// do some stuff...
delete[] objectArray;
现在它编译得很好,运行得很好
但是,当我查看进程的活动监视器时,我发现我分配了 250MB,即使在我执行delete[]
语句之后也不会再次变得可用。有没有办法在不退出 C++ 应用程序的情况下使该内存再次可用?
我在 Mac 上有 C++ 代码,看起来像这样:
Object* objectArray = new Object[1000];
// do some stuff...
delete[] objectArray;
现在它编译得很好,运行得很好
但是,当我查看进程的活动监视器时,我发现我分配了 250MB,即使在我执行delete[]
语句之后也不会再次变得可用。有没有办法在不退出 C++ 应用程序的情况下使该内存再次可用?
仅仅因为内存没有立即再次可用并不意味着当另一个进程请求更多内存时操作系统不会从您的进程中获取它。你所看到的事情发生在很多程序中,并且一遍又一遍地让用户感到困惑,但这通常不值得你花时间。如果没有泄漏就没事。
呼应@sftrabbit 和@pmr:当您分配一块内存时,操作系统至少会为您提供标记为“活动”的内存。您将在系统内存下的活动监视器中看到此术语。然后,当您完成它时,您至少将其中一些标记为“非活动”,这意味着操作系统可以自由地出现并在需要时从您那里获取它。实际上回收它有点昂贵,并且系统假设如果您请求一次内存,您可能会再次想要它,因此除非存在内存压力,否则它不会打扰您。当操作系统确实回收它时,它会将其标记为“免费”,除非其他进程立即需要它。
虽然不一定与您的 C++ 代码相关,但在您的 ObjC 代码中,您会发现已释放的内存甚至可能不会出现在“非活动”池中。Cocoa(实际上是 CoreFoundation)维护分配的内存块池,它可以快速释放。这避免了malloc()
. 与您的问题没有特别相关,但通常在 Mac 应用程序中值得注意。
虽然我普遍同意这不是一个大问题,但我不会对此完全漫不经心。分配和释放大块内存仍然很昂贵,并且可能会迫使系统进入内存压力情况,它必须实际去调试其他进程的内存,从而降低整体系统性能(然后在其他应用程序运行时使其成本更高)需要稍后分配内存)。如果您可以避免它,那么值得尝试保持您的高水位标记(您请求的最大内存)不会不必要地飙升。
但是如果你真的需要这个内存,那也不是问题。内存是可以使用的。
调用new
为对象分配内存。如果空闲存储中没有足够的内存来满足请求,则库会向操作系统请求更多内存。调用delete
不一定会将内存返回给操作系统。假设程序稍后会从空闲存储中使用更多内存,则库通常会挂在该内存上。因此操作系统级别的工具不会显示内存已被释放,因为这些工具不会查看应用程序空闲存储的内部结构。他们所看到的只是操作系统为应用程序提供了一些内存,但还没有取回。