首页 \ 问答 \ 如何确保提交给ThreadPoolExecutor然后取消的FutureTask的垃圾回收?(How to ensure garbage collection of a FutureTask that is submitted to a ThreadPoolExecutor and then cancelled?)

如何确保提交给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$SyncFutureTask同步变量引用。 该FutureTaskFutureTask$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 a ThreadPoolExecutor 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 a FutureTask$Sync's callable variable. That FutureTask$Sync is referenced by a FutureTask's sync variable. That FutureTask is referenced by the FutureTask$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 the ThreadPoolExecutor'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 (with shutdown(), shutdownNow() etc) and also keeping a list of the futures return by submit() 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 just cancel() 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
更新时间:2023-11-08 06:11

最满意答案

测试结果在我的机器上:

  • 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

我进行了分析,发现由于xmlbeanspoi-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_76

I made profiling and found out that XSSF is slow due to the synchronized methods in xmlbeans and poi-ooxml-schemas libraries. You can notify poi developers and ask to check this case.

相关问答

更多
  • 测试结果在我的机器上: 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 ...
  • 我重新解决了问题,这很简单,问题是由于我用阿拉伯语替换法语单词,因此他们只是用来定位我必须修改文本的地方,他们可以是任何一个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 ...
  • 感谢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有哪些限制? 这是非常困难和普遍的问题,只能有非常普遍的答案。 每个软件项目都有不同的要求和功能。 对于每个项目来说,使用第三方组件的可行性很可能也不同。 要选择不同的第三方很困难,因为您需要做更多或更少的事情 需求评估(哪个产品符合您的要求或者紧密满足) 在购买产品之前和之后看看客户支持有多好 第三方产品的功能比较 找到多少稳定的产品。 检查他们发布了多少个版本。 新版本有错误修复,新功能? 独立来源的任何奖项 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 ...
  • 您不能只从一个工作簿中获取Sheet对象,并将其添加到不同的工作簿中。 您需要做的是同时打开旧工作簿和新工作簿,并在新工作簿中创建工作表。 接下来,将旧工作表中使用的所有样式克隆到新工作表(HSSFCellStyle有一种方法,用于将样式从一个工作簿克隆到另一个工作簿)。 最后,迭代所有单元格并将其复制过来。 You can't just take a Sheet object from one Workbook, and add it to a different Workbook. What you'l ...
  • 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 ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。