有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

优化如何回收Java线程堆栈使用的内存?

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

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


共 (4) 个答案

  1. # 1 楼答案

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

    1. 任何仍处于活动状态的线程都不会被垃圾收集。在Thread.start()调用的run方法退出之前,线程一直处于活动状态,无论是正常退出还是抛出异常退出。一旦发生这种情况(线程的未捕获异常处理程序已经完成),线程就死了

    2. 对线程的线程对象的任何实时引用都将防止它被垃圾收集。live引用可以在代码中,或者如果您使用的是线程池,那么它们可能是池数据结构的一部分


    The memory of my java process keeps growing but yet the heap does not increase.

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

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


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

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

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

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

    我建议第一步是使用java提供的线程池来管理线程。util。同时发生的与其创建线程,不如创建交给池的任务。调整池,直到你有一个小得多的线程保持相当繁忙。这可能很好地解决了内存问题;它肯定会提高性能

  3. # 3 楼答案

    Java API文档中的线程在以下情况下死亡:

    All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.

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

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

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

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

  4. # 4 楼答案

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