简体   繁体   English

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

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

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.我知道堆中的 memory 泄漏是由于 object 在堆栈中仍然可以访问/引用,因此 GC 无法清理它。 So my questions are:所以我的问题是:

  1. Does this means that there's still a Java Thread running that owns that Stack memory or not?这是否意味着仍然有一个 Java 线程正在运行,它拥有该堆栈 memory 与否?
  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?如果是,再次运行相同的 Java 线程会增加 memory 泄漏,或者它重新使用堆中的相同对象,因为它们对所有线程都是可见的?
  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?如果不是,泄漏是否发生在堆和堆栈 memory 中,因为堆中的对象必须可以被堆栈访问才能在 GC 中存活?

I'm sorry for these simple questions but I'm having issues to find a clear answer to them.对于这些简单的问题,我很抱歉,但我遇到了问题,无法找到明确的答案。 Thanks!谢谢!

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.我知道堆中的 memory 泄漏是由于 object 在堆栈中仍然可以访问/引用,因此 GC 无法清理它。

That is only one possible cause of memory leaks.这只是 memory 泄漏的可能原因之一。 Another is that there is are unwanted references in a static variables.另一个是static变量中有不需要的引用。 And possibly others as well if you dig deep enough.如果你挖掘得足够深,可能还有其他人。 (For instance, you can create a Java heap memory leak in native code, or by mismanaging classloaders or direct memory buffers, or by running too many threads.) (例如,您可以在本机代码中创建 Java 堆 memory 泄漏,或通过管理不当的类加载器或直接 memory 缓冲区,或通过运行太多线程。)

1) Does this means that there's still a Java Thread running that owns that Stack memory or not. 1)这是否意味着仍然有一个 Java 线程正在运行,该线程拥有该堆栈 memory 与否。

Well a Java thread's stack is removed when it terminates. Java 线程的堆栈在它终止时被删除。 So if a stack exists, that means that its thread has not terminated yet.因此,如果堆栈存在,则意味着其线程尚未终止。 But it may be running, waiting on a lock or blocked in an I/O operation.但它可能正在运行、等待锁定或在 I/O 操作中阻塞。

When a thread terminates, any remaining references held on its stack would immediately become unreachable.当线程终止时,保留在其堆栈上的任何剩余引用将立即变得无法访问。 But technically they became unreachable when the run() method call terminated.但从技术上讲,当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? 2)如果是,再次运行相同的 Java 线程会增加 memory 泄漏,或者它重新使用堆中的相同对象,因为它们对所有线程都是可见的?

If a specific memory leak is caused by a thread, then running the thread again 1 would naturally leak more memory.如果某个特定的 memory 泄漏是由某个线程引起的,那么再次运行该线程1自然会泄漏更多的 memory。 On the other hand, since thread termination of a thread releases all of its references, if you rerun a thread after it has terminated, you don't compound the leak.另一方面,由于线程的线程终止会释放其所有引用,因此如果在线程终止后重新运行线程,则不会加剧泄漏。

Java does not "reuse" objects. Java 不会“重用”对象。 Each time you new a type (class or array) a brand new object is created.每次您new一个类型(类或数组)时,都会创建一个全新的 object。 Always.总是。

Objects in the heap are not visible to all threads.堆中的对象并非对所有线程可见。 They are only visible to the threads that they are reachable from.它们仅对可以访问它们的线程可见。

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

As I said at the start, there are ways to create a memory leak that don't depend on the stack.正如我在开始时所说,有一些方法可以创建不依赖于堆栈的 memory 泄漏。 Objects don't need to be referenced via the stack to be reachable.不需要通过堆栈引用对象即可访问。


1 - I assume we are talking about creating and starting a new Thread with the same or equivalent Runnable as before. 1 - 我假设我们正在讨论使用与以前相同或等效的Runnable创建和启动一个新Thread Technically, a Thread cannot be run (started) twice.从技术上讲,一个Thread不能运行(启动)两次。

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

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