【问题标题】:Memory Leak Java OutOfMemoryError in Vector List向量列表中的内存泄漏 Java OutOfMemoryError
【发布时间】:2012-08-07 15:02:46
【问题描述】:

我正在运行一个具有 3 个线程的多线程应用程序:

  • 主线程 - 存储对象的向量列表
  • AdderThread - 将对象添加到此向量列表
  • RemoverThread - 使用 vectorList.clear() 方法删除对象(同步)

应用程序运行良好,但几个小时后出现 OutOfMemoryError。

我生成了堆转储并使用 eclipse MAT 进行分析,它显示 vectorList 类占用了所有内存。

clear 方法是否释放被单个对象占用的内存?

如何解决这个问题?

【问题讨论】:

  • 你确定你的remove方法被调用了吗?能否在remove方法返回之前添加一个打印向量大小的日志来检查向量是否为空?
  • 是的,在 clear() 被调用后,它会将 Size 打印为 0 。我什至在使用 System.gc();循环中的语句与 3 秒睡眠仍然给出相同的错误

标签: java multithreading memory vector memory-leaks


【解决方案1】:

如果您添加任务的速度快于释放它们的速度,您将收到 OutOfMemoryError,因为您的 Vector 将增长到您的内存限制。

我建议使用并发库中的 BlockingQueue,而不是使用 Vector 作为工作队列。

例如

BlockingQueue<Work> queue = new ArrayBlockingQueue<>(MAX_TASKS_WAITING);

AdderThread calls queue.put(work); // blocks if the queue is full

RemoverThread call queue.take(); // blocks if there is nothing to do.

事实上,使用 ExecutorService 会简单得多,因为它结合了工作队列和线程池。您将任务提交给执行者并由它处理。这避免了为 RemoverThread 编写任何代码的需要。

【讨论】:

  • 谢谢 将尝试使用 BlockingQueue 实现。但是 clear() 方法是否也删除了单个对象占用的内存。每个单独的对象有 2 个哈希图。我将整个对象列表复制到 tempList->vectorList.clear()->process tempList
  • 如果您正确删除,则不需要调用 clear()。仅当您想丢弃某些任务时才调用 clear。例如因为你无法控制等待任务的长度。使用队列,你永远不应该如此绝望。
  • clear() 从支持数组中删除所有元素。但阵列本身保持不变。如果它变得非常大,则空数组可能是导致 OOM 的原因。一个数组最多可以有 2^31 -1 个元素。在 32 位 JVM 上,这表示 8GB。
  • 使用有界集合可以避免这个问题。 ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-18
  • 2013-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多