0

我在 Java 教科书(SL-275)中读到了这个

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

为什么会没有记忆?系统通常有数百 GB 的内存,变量需要 2-8 字节的数据。假设我们有 1000 个未销毁的变量,那只有 8KB。那么为什么垃圾收集如此重要呢?

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

4

4 回答 4

1

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

这很重要,因为,

  1. 你可能会说 8 个字节是一点点数据。但是,如果这 8 个字节在每分钟运行数百万次的紧密循环中泄漏怎么办?你会很快耗尽内存。
  2. 较大的数据结构非常常见。示例:网络爬虫可能会泄漏 HTML 文档的表示形式,轻松达到 100 KB 甚至兆字节。
  3. 尽管内存很便宜,但 100 GB 的 RAM 仍然很少见。你可能会想到磁盘空间,磁盘空间很慢。当您的 RAM 用完并且系统需要在磁盘和 RAM 之间交换内存以执行最简单的操作时,性能将在极端情况下下降。
  4. 还要考虑内存非常有限的移动或嵌入式设备。

真实的战争故事:我曾经调试过一个内存泄漏很小的 ASP .NET 系统(我认为对于特定网页的每个请求大约需要 60 个字节)。但是该页面被大量访问,我们不得不每小时回收应用程序池以避免耗尽服务器上的 RAM。这是在一个非常规范的服务器上。它还表明泄漏甚至可能发生在垃圾收集环境中——我们应该始终注意内存消耗。

于 2012-09-15T16:12:18.833 回答
0

变量可能只包含一两个数据字,但对于类型为某个 Java 对象的变量,该字实际上是指向垃圾收集数据的指针,即对象的状态。并且该对象状态可能反过来包含指向其他对象(或它们的数组)的指针,它们本身指向某个其他对象,或前一个对象(循环引用!)等。

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

我强烈建议至少仔细阅读关于垃圾收集的维基百科页面,然后尽可能阅读垃圾收集手册等教科书。您还可以阅读 Paul Wilson 1992 年的GC 调查文章。

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

于 2012-09-15T16:13:15.063 回答
0

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

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

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

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

于 2012-09-15T16:13:26.780 回答
0

假设您有一个 4Gb 内存的 Web 服务器。在此 Web 服务器上是一个存在少量内存泄漏的网站。

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

也许有泄漏的页面每天被调用 100 次。突然间,我们的服务器每天损失 100mb。这是不好的。

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

于 2012-09-15T16:14:35.553 回答