首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何回收Java线程堆栈使用的内存?

问如何回收Java线程堆栈使用的内存?
EN

Stack Overflow用户
提问于 2009-09-25 19:40:36
回答 4查看 4.3K关注 0票数 2

我已经有好几天的记忆泄漏问题了,我想我现在有了一些线索。我的java进程的内存不断增加,但是堆却没有增加。我被告知,如果我创建了许多线程,这是可能的,因为Java线程使用堆之外的内存。

我的java进程是一个服务器类型的程序,所以有1000-2000线程。正在创建和删除。如何回收java线程使用的内存?我是否只是擦除对线程对象的所有引用并确保它被终止?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-09-25 19:45:42

是。这就是答案。只要有对任何Java对象的活动引用,那么该对象在完成时就不会被垃圾收集。如果您正在创建和销毁线程,而不是集中它们,我认为您也有其他问题。

票数 4
EN

Stack Overflow用户

发布于 2009-09-25 20:22:26

当以下情况下,Java文档中的线程会死掉:

所有不是守护进程线程的线程都已死亡,方法是从对run方法的调用中返回,或者抛出一个在run方法之外传播的异常。

线程从run()方法返回时会死掉。当他们死的时候,他们是垃圾收集的候选人。您应该确保线程释放对对象的所有引用,并退出run()方法。

我不认为取消对线程的引用真的会起作用。

您还应该查看Java 5及更高版本中的新线程处理工具。检查API文档这里中的包这里。

我也建议你去看看这本书实践中的并发性。对我来说是无价之宝。

票数 1
EN

Stack Overflow用户

发布于 2009-09-26 03:23:15

有两件事会导致线程不被垃圾收集。

  1. 任何仍处于活动状态的线程都不会被垃圾收集。线程处于活动状态,直到Thread.start()调用的Thread.start()方法退出为止(正常情况下或通过抛出异常)。一旦发生这种情况(并且线程的非正常异常处理程序已经完成),线程就死了。
  2. 线程的线程对象的任何活动引用都将防止它被垃圾收集。活动引用可能在代码中,或者如果使用线程池,则它们可能是池数据结构的一部分。

我的java进程的内存不断增加,但堆却没有增加。

这将是因为每个线程都有一个没有在Java堆中分配的大堆栈段(例如,1Mb)。

只有在线程启动时才分配线程的堆栈段,并在线程终止时立即释放。同样的情况(我认为)也适用于线程的线程本地映射。没有“活动”的线程对象根本不需要太多内存。

所以总结一下。你似乎有很多活的线索。只要他们活着,他们就不会被垃圾收集,唯一能让他们释放记忆的方法就是让他们死去.不知何故。

要减少内存使用,您需要执行以下一项或多项操作:

  • 看看线程代码( run()方法等),找出它们为什么还在徘徊。
  • 减少线程堆栈的大小。(理论上,你可以低到64K .)
  • 重新设计你的应用程序,这样它就不会创建成千上万的线程。(线程池和某种工作队列是一种可能的方法。)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1479214

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档