在堆内存泄漏期间 Java 线程会发生什么情况?
What happens to the Java Thread during a memory leak in the heap?
我知道堆中的内存泄漏是由于堆栈中仍然 reachable/referenced 的对象造成的,因此 GC 无法清理它。所以我的问题是:
- 这是否意味着仍然有一个 Java 线程 运行 拥有该堆栈内存?
- 如果是,运行 相同的 Java 线程再次会增加内存泄漏,或者它重新使用堆中的相同对象,因为它们对所有线程都是可见的?
- 如果不是,泄漏是否同时发生在堆内存和堆栈内存中,因为堆中的对象必须可由堆栈访问才能在 GC 中存活?
对于这些简单的问题,我深表歉意,但我无法找到明确的答案。谢谢!
I understand that a memory leak in the heap is due to an object that is still reachable/referenced in the stack so the GC can't clean it.
这只是内存泄漏的一个可能原因。另一个是 static
变量中有不需要的引用。如果你挖得足够深,可能还有其他人。 (例如,您可以在本机代码中创建 Java 堆内存泄漏,或者通过管理不当 class 加载程序或直接内存缓冲区,或者通过 运行 使用太多线程。)
1) Does this means that there's still a Java Thread running that owns that Stack memory or not.
好吧,Java 线程的堆栈在终止时被删除。因此,如果堆栈存在,则意味着它的线程尚未终止。但它可能是 运行ning,正在等待锁定或在 I/O 操作中阻塞。
当线程终止时,保留在其堆栈中的任何剩余引用将立即变得无法访问。但从技术上讲,当 run()
方法调用终止时,它们变得无法访问。
2) If yes, running the same Java thread again would increase the memory leak or it re-uses the same objects in the heap since they are visible to all threads?
如果某个特定的内存泄漏是由线程引起的,那么运行再次启用该线程1自然会泄漏更多的内存。另一方面,由于线程的线程终止会释放其所有引用,如果您在线程终止后重新运行 线程,则不会复合 泄漏。
Java 没有 "reuse" 对象。每次 new
类型(class 或数组)都会创建一个全新的对象。总是。
堆中的对象对所有线程都不可见。它们仅对可访问它们的线程可见。
3) If no, does the leak happens in both heap and stack memory as the objects in the heap have to be reachable by the stack to survive a GC?
正如我在开始时所说的,有一些方法可以不依赖于堆栈来创建内存泄漏。不需要通过堆栈引用对象即可访问。
1 - 我假设我们正在谈论创建和开始一个新的 Thread
与以前相同或等效的 Runnable
。从技术上讲,Thread
不能 运行(启动)两次。
我知道堆中的内存泄漏是由于堆栈中仍然 reachable/referenced 的对象造成的,因此 GC 无法清理它。所以我的问题是:
- 这是否意味着仍然有一个 Java 线程 运行 拥有该堆栈内存?
- 如果是,运行 相同的 Java 线程再次会增加内存泄漏,或者它重新使用堆中的相同对象,因为它们对所有线程都是可见的?
- 如果不是,泄漏是否同时发生在堆内存和堆栈内存中,因为堆中的对象必须可由堆栈访问才能在 GC 中存活?
对于这些简单的问题,我深表歉意,但我无法找到明确的答案。谢谢!
I understand that a memory leak in the heap is due to an object that is still reachable/referenced in the stack so the GC can't clean it.
这只是内存泄漏的一个可能原因。另一个是 static
变量中有不需要的引用。如果你挖得足够深,可能还有其他人。 (例如,您可以在本机代码中创建 Java 堆内存泄漏,或者通过管理不当 class 加载程序或直接内存缓冲区,或者通过 运行 使用太多线程。)
1) Does this means that there's still a Java Thread running that owns that Stack memory or not.
好吧,Java 线程的堆栈在终止时被删除。因此,如果堆栈存在,则意味着它的线程尚未终止。但它可能是 运行ning,正在等待锁定或在 I/O 操作中阻塞。
当线程终止时,保留在其堆栈中的任何剩余引用将立即变得无法访问。但从技术上讲,当 run()
方法调用终止时,它们变得无法访问。
2) If yes, running the same Java thread again would increase the memory leak or it re-uses the same objects in the heap since they are visible to all threads?
如果某个特定的内存泄漏是由线程引起的,那么运行再次启用该线程1自然会泄漏更多的内存。另一方面,由于线程的线程终止会释放其所有引用,如果您在线程终止后重新运行 线程,则不会复合 泄漏。
Java 没有 "reuse" 对象。每次 new
类型(class 或数组)都会创建一个全新的对象。总是。
堆中的对象对所有线程都不可见。它们仅对可访问它们的线程可见。
3) If no, does the leak happens in both heap and stack memory as the objects in the heap have to be reachable by the stack to survive a GC?
正如我在开始时所说的,有一些方法可以不依赖于堆栈来创建内存泄漏。不需要通过堆栈引用对象即可访问。
1 - 我假设我们正在谈论创建和开始一个新的 Thread
与以前相同或等效的 Runnable
。从技术上讲,Thread
不能 运行(启动)两次。