繁体   English   中英

在堆中的 memory 泄漏期间,Java 线程会发生什么?

[英]What happens to the Java Thread during a memory leak in the heap?

我知道堆中的 memory 泄漏是由于 object 在堆栈中仍然可以访问/引用,因此 GC 无法清理它。 所以我的问题是:

  1. 这是否意味着仍然有一个 Java 线程正在运行,它拥有该堆栈 memory 与否?
  2. 如果是,再次运行相同的 Java 线程会增加 memory 泄漏,或者它重新使用堆中的相同对象,因为它们对所有线程都是可见的?
  3. 如果不是,泄漏是否发生在堆和堆栈 memory 中,因为堆中的对象必须可以被堆栈访问才能在 GC 中存活?

对于这些简单的问题,我很抱歉,但我遇到了问题,无法找到明确的答案。 谢谢!

我知道堆中的 memory 泄漏是由于 object 在堆栈中仍然可以访问/引用,因此 GC 无法清理它。

这只是 memory 泄漏的可能原因之一。 另一个是static变量中有不需要的引用。 如果你挖掘得足够深,可能还有其他人。 (例如,您可以在本机代码中创建 Java 堆 memory 泄漏,或通过管理不当的类加载器或直接 memory 缓冲区,或通过运行太多线程。)

1)这是否意味着仍然有一个 Java 线程正在运行,该线程拥有该堆栈 memory 与否。

Java 线程的堆栈在它终止时被删除。 因此,如果堆栈存在,则意味着其线程尚未终止。 但它可能正在运行、等待锁定或在 I/O 操作中阻塞。

当线程终止时,保留在其堆栈上的任何剩余引用将立即变得无法访问。 但从技术上讲,当run()方法调用终止时,它们变得无法访问。

2)如果是,再次运行相同的 Java 线程会增加 memory 泄漏,或者它重新使用堆中的相同对象,因为它们对所有线程都是可见的?

如果某个特定的 memory 泄漏是由某个线程引起的,那么再次运行该线程1自然会泄漏更多的 memory。 另一方面,由于线程的线程终止会释放其所有引用,因此如果在线程终止后重新运行线程,则不会加剧泄漏。

Java 不会“重用”对象。 每次您new一个类型(类或数组)时,都会创建一个全新的 object。 总是。

堆中的对象并非对所有线程可见。 它们仅对可以访问它们的线程可见。

3)如果不是,泄漏是否发生在堆和堆栈 memory 中,因为堆中的对象必须可以被堆栈访问才能在 GC 中存活?

正如我在开始时所说,有一些方法可以创建不依赖于堆栈的 memory 泄漏。 不需要通过堆栈引用对象即可访问。


1 - 我假设我们正在讨论使用与以前相同或等效的Runnable创建和启动一个新Thread 从技术上讲,一个Thread不能运行(启动)两次。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM