如何回收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进程的内存一直在增长,但堆却没有增加。有人告诉我,如果创建多个线程,这是可能的,因为java线程使用堆外的内存


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

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

来自Java API文档,线程在以下情况下死亡:

所有不是守护进程线程的线程都已死亡,要么是通过调用run方法返回,要么是通过抛出传播到run方法之外的异常


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

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

您还应该查看Java5及更高版本中的新线程功能。检查API文档中的包java.util.concurrent


我还建议你查一下这本书。这对我来说是无价的。

这是很多线程,每个线程都会带来内存开销,以及管理它们的其他资源(上下文切换等)。使用探查器查看线程活动-您可能会发现大多数线程大部分时间处于空闲状态


我建议第一步是使用java.util.concurrent提供的线程池来管理线程。与其创建线程,不如创建交给池的任务。调整池,直到有更少的线程保持合理的繁忙状态。这可以很好地解决内存问题;它肯定会提高性能

有两种情况会导致线程不被垃圾收集

  • 任何仍处于活动状态的线程都不会被垃圾收集。线程一直处于活动状态,直到
    thread.start()
    调用的
    run
    方法正常退出或抛出异常退出。一旦发生这种情况(并且线程的未捕获异常处理程序已经完成),线程就死了

  • 对线程的线程对象的任何活动引用都将防止对其进行垃圾收集。live引用可以在代码中,或者如果您使用的是线程池,那么它们可以是池数据结构的一部分


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

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

    线程的堆栈段仅在线程启动时分配,并在线程终止时释放。我认为这同样适用于线程的线程局部映射。非“活动”的线程对象根本不会占用太多内存


    总而言之。您似乎有很多活动线程。只要他们活着,就不会被垃圾收集,让他们释放记忆的唯一方法就是让他们死去。。。不知怎么的

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

    • 查看线程代码(
      run()
      方法等),找出它们仍然存在的原因
    • 减小线程堆栈的大小。(理论上,你可以低至64K…)
    • 重新设计你的应用程序,这样它就不会产生成千上万的线程。(线程池和某种工作队列是一种可能的方法。)

    “当它们死亡时,它们是垃圾收集的候选对象”,但前提是没有其他对象仍然持有对这些死亡线程的引用。