Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
向量列表中的内存泄漏Java OutOfMemoryError_Java_Multithreading_Memory_Vector_Memory Leaks - Fatal编程技术网

向量列表中的内存泄漏Java OutOfMemoryError

向量列表中的内存泄漏Java OutOfMemoryError,java,multithreading,memory,vector,memory-leaks,Java,Multithreading,Memory,Vector,Memory Leaks,我正在运行一个具有3个线程的多线程应用程序: 主线程-用于存储对象的向量列表 AdderThread-将对象添加到此向量列表 RemoveThread-使用vectorList.clear()方法删除对象(已同步) 应用程序运行正常,但几个小时后就会出现OutOfMemoryError 我生成了堆转储并用EclipseMat进行了分析,它显示vectorList类占用了所有内存 是否清除方法释放单个对象占用的内存 如何解决此问题?如果添加任务的速度比释放任务的速度快,则会出现OutOfMem

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

  • 主线程-用于存储对象的向量列表
  • AdderThread-将对象添加到此向量列表
  • RemoveThread-使用vectorList.clear()方法删除对象(已同步)
应用程序运行正常,但几个小时后就会出现OutOfMemoryError

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

是否清除
方法释放单个对象占用的内存


如何解决此问题?

如果添加任务的速度比释放任务的速度快,则会出现OutOfMemory错误,因为向量将增长到内存的极限

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

e、 g

BlockingQueue=newarrayblockingqueue(最大任务等待时间);
AdderRead调用队列。放置(工作);//如果队列已满,则阻塞
删除线程调用队列。take();//如果无事可做,就会阻塞。

事实上,使用ExecutorService要简单得多,因为它将工作队列与线程池结合在一起。您将任务提交给执行者,执行者将对其进行处理。这样就不需要为RemoveThread本身编写任何代码。

您确定调用了
remove
方法吗?在
remove
方法返回以检查向量是否为空之前,是否可以添加一个打印向量大小的日志?调用clear()后,它将大小打印为0。我甚至在使用System.gc();语句在循环中使用3秒睡眠时仍会出现相同的错误感谢您尝试使用BlockingQueue实现。但是clear()方法不也会删除单个对象占用的内存吗。每个对象都有2个哈希映射。我在templast->vectorList.clear()->process templalist中复制整个对象列表,如果您正确地删除了,您不需要调用clear()。仅当要放弃某些任务时才调用clear。e、 因为你无法控制等待任务的长度。使用队列时,您不应该如此绝望。clear()将从备份数组中删除所有元素。但阵列本身没有被触动。如果它变得非常大,则空数组可能是导致OOM的原因。一个数组最多可以有2^31-1个元素。在32位JVM上,表示8GB。使用有界集合可以避免此问题。;)
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.