如何回收Java线程堆栈使用的内存?
我已经有好几天的内存泄漏问题了,我想我现在有了一些线索。我的java进程的内存一直在增长,但堆却没有增加。有人告诉我,如果创建多个线程,这是可能的,因为java线程使用堆外的内存如何回收Java线程堆栈使用的内存?,java,optimization,memory,memory-management,memory-leaks,Java,Optimization,Memory,Memory Management,Memory Leaks,我已经有好几天的内存泄漏问题了,我想我现在有了一些线索。我的java进程的内存一直在增长,但堆却没有增加。有人告诉我,如果创建多个线程,这是可能的,因为java线程使用堆外的内存 我的java进程是一个服务器类型的程序,因此有1000-2000个线程。正在创建和删除。如何回收java线程使用的内存?我是否只是删除对thread对象的所有引用并确保其已终止?是。这就是答案。只要存在对任何Java对象的活动引用,那么该对象在完成时就不会被垃圾收集。 如果您正在创建和销毁线程,而不是共享线程,我认为您
我的java进程是一个服务器类型的程序,因此有1000-2000个线程。正在创建和删除。如何回收java线程使用的内存?我是否只是删除对thread对象的所有引用并确保其已终止?是。这就是答案。只要存在对任何Java对象的活动引用,那么该对象在完成时就不会被垃圾收集。
如果您正在创建和销毁线程,而不是共享线程,我认为您还存在其他问题。来自Java API文档,线程在以下情况下死亡: 所有不是守护进程线程的线程都已死亡,要么是通过调用run方法返回,要么是通过抛出传播到run方法之外的异常
线程从run()方法返回时会死亡。当他们死后,他们是垃圾收集的候选者。您应该确保线程释放对对象的所有引用并退出run()方法 我认为取消对线程的引用不会真正起作用 您还应该查看Java5及更高版本中的新线程功能。检查API文档中的包java.util.concurrent
我还建议你查一下这本书。这对我来说是无价的。这是很多线程,每个线程都会带来内存开销,以及管理它们的其他资源(上下文切换等)。使用探查器查看线程活动-您可能会发现大多数线程大部分时间处于空闲状态
我建议第一步是使用java.util.concurrent提供的线程池来管理线程。与其创建线程,不如创建交给池的任务。调整池,直到有更少的线程保持合理的繁忙状态。这可以很好地解决内存问题;它肯定会提高性能 有两种情况会导致线程不被垃圾收集
thread.start()
调用的run
方法正常退出或抛出异常退出。一旦发生这种情况(并且线程的未捕获异常处理程序已经完成),线程就死了我的java进程的内存不断增长,但堆没有增加 这是因为每个线程都有一个大的(例如1Mb)堆栈段,而这个堆栈段没有在Java堆中分配 线程的堆栈段仅在线程启动时分配,并在线程终止时释放。我认为这同样适用于线程的线程局部映射。非“活动”的线程对象根本不会占用太多内存
总而言之。您似乎有很多活动线程。只要他们活着,就不会被垃圾收集,让他们释放记忆的唯一方法就是让他们死去。。。不知怎么的 要减少内存使用,您需要执行以下一项或多项操作:
- 查看线程代码(
方法等),找出它们仍然存在的原因李>run()
- 减小线程堆栈的大小。(理论上,你可以低至64K…)
- 重新设计你的应用程序,这样它就不会产生成千上万的线程。(线程池和某种工作队列是一种可能的方法。)