-2

在我们的一个 java 应用程序中,我们得到了 OutOfMemoryError:GC Overhead limit exceeded.

我们在某些地方使用了 HashMaps 来存储一些数据。从日志中我们可以确定它在同一个地方复制。

我想问一下垃圾收集器是否花费更多时间来清理哈希图?

查看代码后(我不能在这里分享),我发现有一个像这样创建的 Hashmap

Hashmap topo = new HashMap();

但是这个哈希图从未被使用过。这是我的应用程序中的一种内存泄漏吗?

如果这Hashmap是在一个正在做一些处理的方法中创建的,并且它没有在其他地方使用,那么这个方法也被访问我的多个线程说 20 。那么在这种情况下,它会影响,创建如上所述的 Hashmap,垃圾收集器花费更多时间在恢复堆并抛出 OOME。

如果您需要更多详细信息,请告诉我。

4

3 回答 3

0

在我们的一个 java 应用程序中,我们遇到了 OutOfMemoryError:GC Overhead limit exceeded。我们在某些地方使用了 HashMaps 来存储一些数据。从日志中我们可以确定它在同一个地方复制。

如果 Hashmap 只是简单地构建并且很可能标记为静态,这意味着您不断向此 hashmap 添加内容并且永远不会删除。然后有一天它会导致 OutOfMemoryError。

我想问一下垃圾收集器是否花费更多时间来清理哈希图?

垃圾收集器将时间花在未引用、弱引用、软引用的对象上。无论它在哪里找到这样的物体,它都会根据需要清除它们。

查看代码后(我不能在这里分享),我发现有一个像 Hashmap topo = new HashMap(); 这样创建的 Hashmap。,但从未使用过此哈希图。这是我的应用程序中的一种内存泄漏吗?

如果这个 Hashmap 是在一个正在做一些处理的方法中创建的,并且它没有在其他地方使用,那么这个方法也被访问我的多个线程说 20 。那么在这种情况下,它会影响,如上创建 Hashmap,垃圾收集器花费更多时间来恢复堆并抛出 OOME。

如果它是methid本地的hashmap,并且该方法在进行一些处理后退出,那么它应该在方法退出后立即被垃圾回收。由于 hashmap 对方法来说是本地的,所以每个线程都会有这个 map 的单独副本,一旦线程完成方法执行,map 就有资格进行 GC。

于 2013-07-15T10:49:25.323 回答
0

您需要寻找可能是实际问题的长期对象和结构,而不是疯狂地抓住一些无知的经理对潜在问题的想法。

看:

特别注意静态/或应用程序生命周期的地图或列表,它们是在生命周期中添加的,而不仅仅是在初始化时。它很可能是其中一个或几个正在积累的。

另请注意,内部类(Listeners、Observers)可以捕获对其包含范围的引用并防止它们被无限期地 GC'ed。

于 2013-07-15T11:00:49.510 回答
0

如果您需要更多详细信息,请告诉我。

需要更多细节。您需要分析您的应用程序以查看哪些对象正在消耗堆空间。

然后,如果您的应用程序实际上不再使用某些相当大的对象,那么您就会发生内存泄漏。查看对这些对象的引用,找出当它们不再有用时它们仍然保留在内存中的原因,然后修改您的代码以不再保留这些引用。

或者,您可能会发现内存中的所有对象都是您期望的工作集。然后您需要增加堆大小,或者重构您的应用程序以使用较小的工作集(例如,一次一个流式事件而不是读取整个列表;将最后一次看到的详细信息存储在数据库中而不是内存中;等等。 )。

于 2013-07-15T11:06:46.320 回答