如果我有一个(或多个)可完成的未来
尚未启动,并且在该方法上有几个,那么ApplyAsync()
,任何Of()
方法。
垃圾收集器会移除所有这些吗?
如果在该链的末尾有一个< code > join()/< code > get()
也许我们需要更多关于连接上下文的信息()。
这种连接是线程中的最后一个命令,并且没有副作用。那么在这种情况下,线程仍然是活动的吗?- Java线程垃圾收集与否
无论如何,这是一个好主意,如果我确信(也许在尝试捕获中),那么将一个平衡药丸推向链条,我不会启动那个可完成链条,或者没有必要吗?
问题是因为这样?(https://bugs.openjdk.java.net/browse/JDK-8160402)
与此相关的一些问题:线程执行器何时被通知调度新任务?我想,当CompletableFuture
转到下一个链接时?。所以我必须只进行内存泄漏,而不是线程泄漏?
编辑:我指的是一个尚未开始的CompletableFuture?
我指的是var < code > notStartedCompletableFuture = new CompletableFuture
我可以这样启动notStartedCompletableFuture:< code > notStartedCompletableFuture . complete(new Object);在程序流的后面或从另一个线程。
编辑2:更详细的示例:
AtomicReference<CompletableFuture<Object>> outsideReference=new AtomicReference<>();
final var myOuterThread = new Thread(() ->
{
final var A = new CompletableFuture<Object>();
final var B = new CompletableFuture<Object>();
final var C = A.thenApplyAsync((element) -> new Object());
final var D = CompletableFuture.anyOf(A, C);
A.complete(new Object());
// throw new RuntimeException();
//outsideReference.set(B);
----->B.complete(new Object());<------ Edit: this shouldn't be here, i remove it in my next iteration
D.join();
});
myOuterThread.start();
//myOutherThread variable is nowhere else referenced, it's sayed so a local variable, to point on my text on it^^
这里还有一个问题,如果线程通过等待join()
而被阻塞,或者返回到线程池,我如何证明这种行为?,其中线程也“阻塞”?
本答案仅针对“编辑2”中的3个后续问题。
我假设您指的是带有注释掉语句的版本。
线程中的< code>CompletableFutures永远不会完成。
不正确。首先,< code>A在这里完成:
A.complete(new Object());
下一个B
在这里完成:
B.complete(new Object());
然后调用D.join()
。因为D
是一个anyOf
stage,所以当
完成时,这就完成了
A
已经完成,所以
D。join()
可能不需要等待
CC
异步应用函数,它也可以立即完成。
通常情况下,GC可以安全地清除线程和其中的内容,即< code>CompletableFutures。但我不认为会发生这种事。
当<代码>D时。join()返回,线程终止。此时,它的局部局部变量(A
、BC
和D
>)将无法访问。
A
像以前一样完成,但B
、C
和D
没有。
但是,异常终止了线程,因此局部变量< code>A 、< code>B 、< code>C和< code>D变得不可访问。
三点:
>
原子引用
被分配到 B
,因此 D
上的连接 ()
不受影响。
如上所述,对于变量< code>A 、< code>B 、< code>C和< code>D,假设的< code > join() on < code > outsidereference . value()是否发生并不重要。无论线程以何种方式终止,这些变量都变得不可访问。
但是,您现在已经将对其中一个可完成未来
对象的引用分配给了与线程具有不同生存期的变量。这可能意味着,在线程终止后,可完成未来
对象将保持可访问状态。
如果线程对永远不会完成的CompletableFuture
调用join()
或
,它将永远保持阻塞状态(除非被中断),并保留对该未来的引用。
如果该未来是后代未来链(任务和执行器)的根,它还将保留对这些未来的引用,这些引用也将保留在内存中(以及所有可传递引用的对象)。
通过 then*
() 方法创建时,future 通常不会保存对其“父(s)”的引用,因此,如果没有其他引用,则通常应对其进行垃圾回收 - 但要注意这些引用,例如调用线程中的局部变量,对列表的引用
你似乎在纠结于CompletableFuture
可能泄露的不同方式,这取决于你是如何创建它的。但是它是如何、在哪里、何时或为什么创建并不重要。唯一重要的是它是否仍然可以访问。
垃圾收集器会移除所有这些吗?
我们预计有两个地方会引用CompletableFuture:
Runnable
(或其他)中,这将完成未来。如果您有一个调用,那么ApplyAsync()
或anyOf()
,则该调用的参数中包含引用
。如果调用仍然可以发生,那么对
Runnable
的引用必须仍然可以访问。
在你的例子中:
var notStartedCompletableFuture = new CompletableFuture<Object>();
如果变量notStartedCompletableFuture
仍可被某些仍在执行的代码访问,则该CompletableFuture
是可访问的并且不会被垃圾回收。
另一方面,如果< code > notStartedCompletableFuture 不再可访问,并且如果未来不再可通过其他路径到达,那么它将根本不可到达...并将成为垃圾收集的候选对象。
如果在该链的末尾有一个join()-
这没什么区别。这都是基于可达性。(唯一的问题是当前活动的线程1始终是可达的,而不管对其
Thread
对象的任何其他引用如何。这同样适用于它的Runnable
,以及从Runnable
可达的其他对象。)
但是值得注意的是,如果您在一个永远不会终止/完成的线程/ future上调用< code>join()
或< code> get(),您将会阻塞当前线程,可能是永远阻塞。这就像线漏了一样糟糕。
< sup>1 -线程从启动到终止都是“活动的”。
线程执行器什么时候发出信号来安排新任务?
这取决于你所说的“时间表”是什么意思。如果你的意思是,任务什么时候提交,那么答案就是调用< code>submit的时候。如果你的意思是,它实际上什么时候运行...它进入队列,当它到达队列头时运行,一个工作线程可以自由执行它。
在< code>thenApplyAsync()和< code>all_of()的情况下,任务被提交(即< code>submit(...) call occurs)当相应的方法调用发生时。因此,举例来说,如果< code>thenApplyAsync是根据先前调用的结果调用的,那么该调用必须首先返回。
这都是Java表达式求值的基本属性的结果...应用于用于构造阶段链的表达式。
通常,您不需要尝试/最终或尝试使用资源来清理潜在的内存泄漏。
你所需要做的就是确保你没有在变量、数据结构等中保留对各种未来、阶段等的引用,这些引用在你的计算生命周期之外仍然是可访问的。如果你这样做了……这些引用很可能是泄漏的来源。
线程泄漏不应该是您的关注点。如果您的代码未显式创建线程,则它们由执行器服务/池管理。
问题内容: 我有一个奇怪的疑问。我知道垃圾收集器有其自身的局限性。如果分配不正确,则可能导致应用程序以异常方式响应。 所以我的问题是,在每个活动结束时强制调用垃圾回收器()是良好的编程习惯吗? 更新资料 每个人都说调用system.gc()根本没有好处。然后,我想知道为什么它出现在这里。DVM将决定何时运行垃圾收集器。那么,该方法需要什么? 更新2 感谢社区的帮助。但老实说,我从此链接中获得了有关
问题内容: 我想触发许多一次性异步CompletableFutures,例如: 理想情况下,可以在完成后将这些CompletableFutures进行垃圾回收。但是,由于我没有存储参考文献,因此是否有事先收集它们的风险? 问题答案: 您不是在显式地存储引用,而是在内部。该方法创建一个,然后向其提交引用的任务(如果您使用的是公共池)。在返回的变成了依赖于第一,因此也被引用。 一旦完成的执行,将第一个
Kubernetes 垃圾收集器的角色是删除指定的对象,这些对象曾经有但以后不再拥有 Owner 了。 注意:垃圾收集是 beta 特性,在 Kubernetes 1.4 及以上版本默认启用。 Owner 和 Dependent 一些 Kubernetes 对象是其它一些的 Owner。例如,一个 ReplicaSet 是一组 Pod 的 Owner。具有 Owner 的对象被称为是 Owner
本文向大家介绍Java垃圾收集,包括了Java垃圾收集的使用技巧和注意事项,需要的朋友参考一下 示例 C ++方法-新增和删除 在像C ++这样的语言中,应用程序负责管理动态分配的内存所使用的内存。当使用new运算符在C ++堆中创建对象时,需要相应地使用delete运算符来处置该对象: 如果程序忘记了delete一个对象而只是“忘记”了该对象,则关联的内存将丢失给应用程序。这种情况的术语是内存泄
JavaScript 具有自动垃圾收集机制,也就是说,执行环境会负责管理代码执行过程中使用的内存。 而在C 和C++之类的语言中,开发人员的一项基本任务就是手工跟踪内存的使用情况,这是造成许多问题的一个根源。在编写JavaScript 程序时,开发人员不用再关心内存使用问题,所需内存的分配以及无用内存的回收完全实现了自动管理。这种垃圾收集机制的原理其实很简单:找出那些不再继续使用的变量,然后释放其
Java 15 使 ZGC、Z 垃圾收集器成为标准功能。它是 Java 15 之前的一个实验性功能。它是低延迟、高度可扩展的垃圾收集器。 ZGC 是在 Java 11 中作为一项实验性功能引入的,因为开发人员社区认为它太大而无法提前发布。 即使在机器学习应用程序等海量数据应用程序的情况下,ZGC 也具有高性能和高效工作。它确保在处理数据时不会因垃圾收集而长时间停顿。它支持 Linux、Window