记忆泄漏的概念

时间:2012-09-15 16:08:32

标签: memory-leaks garbage-collection

我在Java教科书(SL-275)

中读到了这个
  

当系统上没有剩余内存要分配时,不取消分配内存的程序最终会崩溃。据说这些程序有内存泄漏

为什么没有内存?系统通常具有数百GB的内存,变量需要2-8字节的数据。假设我们有1000个未被破坏的变量,那只有8KB。 那么为什么垃圾收集很重要?

我尝试在网上搜索答案,甚至接近我的讲师,但找不到满意的答案。

4 个答案:

答案 0 :(得分:1)

如果程序使用完变量后系统无法回收内存,则会发生内存泄漏。

这很重要,因为,

  1. 您可能会说8个字节是一点点数据。但是,如果这8个字节在每分钟运行数百万次的紧密循环中泄漏怎么办?你会很快耗尽记忆力。
  2. 更大的数据结构非常常见。示例:Web scraper可能会泄露HTML文档的表示,容易100个KB或甚至兆字节。
  3. 虽然内存很便宜,但100 GB的内存仍然不常见。您可能会考虑磁盘空间,并且磁盘空间很慢。当你耗尽了RAM并且系统需要在磁盘和RAM之间交换内存来执行最简单的操作时,性能会在极端情况下降低。
  4. 还要考虑内存非常有限的移动设备或嵌入式设备。
  5. 真正的战争故事:我曾经调试过具有微小内存泄漏的ASP .NET系统(我认为每个请求对特定网页大约有60个字节)。但该页面已经很多,我们不得不每小时回收应用程序池,以避免耗尽服务器上的RAM。这是一个非常好的服务器。它还表明泄漏甚至可能发生在垃圾收集环境中 - 我们应该始终注意内存消耗。

答案 1 :(得分:0)

变量可能只包含一个或两个单词的数据,但对于其类型为某个Java对象的变量,该单词实际上是指向垃圾收集数据的指针,即对象的状态。而且该对象状态又可以包含指向其他对象(或它们的数组)的指针,它们自己指向其他对象,或前一个对象(循环引用!)等。

垃圾收集器只有在确定没有引用链(来自本地或全局变量)指向它之后才会释放(即让JVM重用)内存。

我强烈建议至少仔细阅读garbage collection上的维基百科页面,然后尽可能阅读像the garbage collection handbook这样的教科书。您还可以阅读1992年Paul Wilson的GC survey文章。

你应该关心RAM的使用情况;从应用程序的角度来看,访问硬盘需要很长时间(在磁盘上访问一个千字节块大约需要10毫秒。在RAM上访问它是几个微时间,快一千倍的时间;片上缓存是可在纳秒内访问。 SSD让它变得更好。

答案 2 :(得分:0)

首先,假设所有变量都是2到8个字节,这是一个很大的假设。有些可能是相当大的数据结构,在某些应用程序中可能是兆字节。

其次,即使是2字节的可变泄漏也会造成严重破坏,如果它处于数百万或数十亿次的循环中,尤其是在长期存在的程序中。

第三,您拥有的物理内存量可能与您的进程地址空间无关。例如,32位进程可能只能处理4G,无论您的机器有数百GB的事实。

最后,即使你可以处理泄漏,更好的编码风格也会有这些潜在的错误。其他任何事情都只是草率: - )

答案 3 :(得分:0)

假设你有一台4Gb ram的网络服务器。在这个Web服务器上是一个网站,内存泄漏很少。

对于这个例子,假设他们每个人都消耗一些文件,这个文件需要RAM中的1Mb内存,并且在使用后不要清理它。

可能每天有100次调用有泄漏的页面。我们的服务器突然每天损失100mb。这很糟糕。

内存泄漏可能很小,但您不希望每30天重新启动一次应用程序,因为它会占用您的所有内存。