如何确保提交给ThreadPoolExecutor然后取消的FutureTask的垃圾回收?(How to ensure garbage collection of a FutureTask that is submitted to a ThreadPoolExecutor and then cancelled?)
我将
Callable
对象提交给一个ThreadPoolExecutor
,它们似乎在内存中存在。查看带有用于Eclipse的MAT工具的堆转储,看到可调对象被
FutureTask$Sync
的可调用变量引用。FutureTask$Sync
由FutureTask
的同步变量引用。 该FutureTask
由FutureTask$Sync
的$ 0变量引用。我已经阅读了关于这个( 这里 , 在这里 ,以及所以),并且它看起来像
FutureTask
,可调用包装在ThreadPoolExecutor
的submit()持有永久可调用的引用。我感到困惑的是如何确保
FutureTask
得到垃圾收集,因此它不会继续在内存中保存可调用对象,并且保存可调用对象可能在内存中保留的任何内容?只是为了提供有关我的特定情况的更多细节,我试图以允许所有提交的任务在需要时被取消的方式实现
ThreadPoolExecutor
。 我尝试了几种不同的方法,我在SO和其他地方找到了一些方法,例如完全关闭执行程序(使用shutdown()
,shutdownNow()
等),并通过submit()
和调用cancel来保存期货的列表然后清除期货清单。 理想情况下,我不想关闭它,只需cancel()
并在需要时清除。所有这些方法似乎都没有区别。 如果我向池中提交一个可调用的函数,那么它很可能会结束。
我究竟做错了什么?
谢谢。
编辑:
按照要求,这是ThreadPoolExecutor的构造函数。
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); }
进一步测试后,我可以看到,如果我让已提交给ThreadPoolExecutor的任务完成,那么就没有泄漏。 如果我尝试取消它们,例如:
shutdownNow()
或者保存对未来的引用并稍后调用cancel:
Future referenceToCancelLater = submit(task); ... referenceToCancelLater.cancel(false);
或者使用如下方法将它们从队列中删除:
getQueue.drainTo(someList)
要么
getQueue.clear()
或循环保存期货和电话的参考:
getQueue.remove(task)
如上所述,任何这些情况都会导致FutureTask停滞不前。
所以真正的问题是如何正确地取消或移除ThreadPoolExecutor中的项目,以便FutureTask被垃圾回收并且不会永远泄漏?
I am submitting
Callable
objects to aThreadPoolExecutor
and they seem to be sticking around in memory.Looking at the heap dump with the MAT tool for Eclipse see that the
Callable
objects are being referenced by aFutureTask$Sync
's callable variable. ThatFutureTask$Sync
is referenced by aFutureTask
's sync variable. ThatFutureTask
is referenced by theFutureTask$Sync
's this$0 variable.I have read around about this (here, here, and on SO) and it seems like the
FutureTask
that the callable is wrapped in upon theThreadPoolExecutor
's submit() holds a reference to the callable forever.What I am confused about is how to ensure that the
FutureTask
gets garbage collected so it doesn't continue to hold the callable in memory, and hold anything the callable might be holding in memory?Just to give more details about my particular situation, I am trying to implement the
ThreadPoolExecutor
in a way that allows all of the submitted tasks to be canceled if needed. I have tried several different methods I found on SO and elsewhere, such as completely shutting the executor down (withshutdown()
,shutdownNow()
etc) and also keeping a list of the futures return bysubmit()
and calling cancel on all them and then clearing the list of futures. Ideally I would like not to have to shut it down, and justcancel()
and clear out when needed.All of these methods don't seem to make a difference. If I submit a callable to the pool, there is a good chance it will end up sticking around.
What am I doing wrong?
Thanks.
Edit:
As requested, here is the constructor for the ThreadPoolExecutor.
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); }
After further testing I can see that if I let the tasks that have been submitted to the ThreadPoolExecutor finish, then there is no leak. If I try to cancel them in anyway such as:
shutdownNow()
Or saving a reference to the future and calling cancel on it later:
Future referenceToCancelLater = submit(task); ... referenceToCancelLater.cancel(false);
Or by removing them from the queue with methods like:
getQueue.drainTo(someList)
or
getQueue.clear()
or Looping through saved references to the futures and calling:
getQueue.remove(task)
Any of those cases causes the FutureTask to stick around as described above.
So the real question in all of this is how to I properly cancel or remove items from a ThreadPoolExecutor so that the FutureTask is garbage collected and not leaked forever?
原文:https://stackoverflow.com/questions/4917039
最满意答案
测试结果在我的机器上:
- HSSF:2秒
- SXSSF:5秒
- XSSF:27秒
机器规格:
CPU: Intel i3-2100, 3.10 GHz, 4-cores RAM: 16GB OS: Windows 7 64bit JDK: 1.7.0_76我进行了分析,发现由于
xmlbeans
和poi-ooxml-schemas
库中的同步方法,xmlbeans
速度很慢。 您可以通知poi开发人员并要求检查此案例。Test results on my machine:
- HSSF: 2 sec
- SXSSF: 5 sec
- XSSF: 27 sec
Machine specs:
CPU: Intel i3-2100, 3.10 GHz, 4-cores RAM: 16GB OS: Windows 7 64bit JDK: 1.7.0_76I made profiling and found out that
XSSF
is slow due to the synchronized methods inxmlbeans
andpoi-ooxml-schemas
libraries. You can notify poi developers and ask to check this case.
相关问答
更多-
Apache POI性能(Apache POI Performance)[2021-11-08]
测试结果在我的机器上: HSSF:2秒 SXSSF:5秒 XSSF:27秒 机器规格: CPU: Intel i3-2100, 3.10 GHz, 4-cores RAM: 16GB OS: Windows 7 64bit JDK: 1.7.0_76 我进行了分析,发现由于xmlbeans和poi-ooxml-schemas库中的同步方法, xmlbeans速度很慢。 您可以通知poi开发人员并要求检查此案例。 Test results on my machine: HSSF: 2 sec SXSSF: ... -
Android正在使用与Java正则表达式引擎略有不同的ICU正则表达式库。 看到这个参考 : Unicode脚本,块,类别和二进制属性使用Perl中的\p和\P结构编写。 如果输入具有属性prop,则\p{prop}匹配,而如果输入具有该属性,则\P{prop}不匹配。 因此,模式应该写成 Pattern nonAlphabeticPattern = Pattern.compile("\\P{L}"); Android is using ICU regex library that is a bit ...
-
apache poi从右到左(right to left with apache poi)[2022-04-05]
我重新解决了问题,这很简单,问题是由于我用阿拉伯语替换法语单词,因此他们只是用来定位我必须修改文本的地方,他们可以是任何一个charchter,更合适的是阿拉伯语! i resloved the problem it's so simple , the problem is due that i replace french word with arab ones and since this they are just a words used to locate where i have to modi ... -
使用Apache poi设置边距(Set margins with Apache poi)[2023-01-30]
感谢Gagravarr指出我正确的方向。 似乎我没有完整的ooxml-schemas-1.1.jar。 此代码现在可以完美地设置边距 CTSectPr sectPr = document.getDocument().getBody().addNewSectPr(); CTPageMar pageMar = sectPr.addNewPgMar(); pageMar.setLeft(BigInteger.valueOf(720L)); pageMar.setTop(BigInteger.valu ... -
Apache POI和Aspose?(Apache POI and Aspose?)[2022-02-28]
任何人都可以向我建议我应该去哪一个? Apache POI和Aspose有哪些限制? 这是非常困难和普遍的问题,只能有非常普遍的答案。 每个软件项目都有不同的要求和功能。 对于每个项目来说,使用第三方组件的可行性很可能也不同。 要选择不同的第三方很困难,因为您需要做更多或更少的事情 需求评估(哪个产品符合您的要求或者紧密满足) 在购买产品之前和之后看看客户支持有多好 第三方产品的功能比较 找到多少稳定的产品。 检查他们发布了多少个版本。 新版本有错误修复,新功能? 独立来源的任何奖项 API和文档的总体可用 ... -
将评论提升为答案... Apache POI具有少量依赖关系 ,这些依赖关系完全列在网站的“ 组件”页面上。 您需要包含您正在使用的任何POI模块的依赖项。 在您的情况下,您获得的异常表明Commons Codec库缺失,并补充说明了解决问题。 Promoting a comment to an answer... Apache POI has a small number of dependencies, which are fully listed on the Components page on t ...
-
Apache POI。(Apache POI. Copying sheets)[2021-12-06]
您不能只从一个工作簿中获取Sheet对象,并将其添加到不同的工作簿中。 您需要做的是同时打开旧工作簿和新工作簿,并在新工作簿中创建工作表。 接下来,将旧工作表中使用的所有样式克隆到新工作表(HSSFCellStyle有一种方法,用于将样式从一个工作簿克隆到另一个工作簿)。 最后,迭代所有单元格并将其复制过来。 You can't just take a Sheet object from one Workbook, and add it to a different Workbook. What you'l ... -
Java Apache POI(Java Apache POI)[2022-11-01]
1.在java中解决OutOfMemoryError的简单方法是使用JVM选项"-Xmx512M"来增加最大堆大小,这将立即解决你的OutOfMemoryError。 Java虚拟机(JVM)以固定的内存上限运行,您可以对其进行修改: -Xms- Set initial Java heap size -Xmx - Set maximum Java heap size $ java -Xms512m -Xmx1024m JavaApp 2.解决Java中的OutOfMemoryE ... -
我们当然可以在Android中移植Apache POI API。 我做的示例代码是在Apache POI的帮助下计算功率点演示中的幻灯片数量。 We can certainly port Apache POI API in Android. The example code that i made is to count the number of slides in a power point presentation with the help of Apache POI.
-
这个stackoverflow帖子帮助了我。 我不得不删除META-INF中的一些文件并重新压缩文件夹并将其重命名为jar是不够的,我需要用这个命令实际创建jar: jar cvf org.apache.poi_3.9.0.v201303080712.jar . This stackoverflow post helped me. I had to delete a few files in META-INF and also rezipping the folder and renaming it to ...