gpt4 book ai didi

java - 如果未正确完成 RestEasyClient JAX RS 可能会出现资源泄漏

转载 作者:行者123 更新时间:2023-12-02 10:55:03 25 4
gpt4 key购买 nike

问题:我有一个休息客户端,应该将请求发送到 URL。 java应用程序是一个独立的java应用程序(以 java -jar 启动),然后在退出时关闭所有应用程序上下文。但应用程序将结束但不会关闭,并且 PID 仍保留给 java 进程。对于每个请求,我都进行异步调用并在 InvocableCallback 实现中获取响应。

 client = new ResteasyClientBuilder().connectTimeout(timeout, TimeUnit.SECONDS).readTimeout(timeout, TimeUnit.SECONDS).httpEngine(engine).build();
ResteasyWebTarget resteasyWebTarget = client.target(url));
Future<Response> response = resteasyWebTarget.
request().
headers(headers).
async().
get(restResponseCallback);

即使在对测试 URL 进行一次测试调用之后,即使所有上下文都已关闭,我的应用程序也不会关闭。

应用程序上下文已关闭,如中所述 Spring ApplicationContext.close() doesnot shut down application

最佳答案

简而言之,问题是我正在根据每个请求创建一个新客户端。

我“关闭”了应用程序,然后查找在关闭后始终挂起的 java 进程的幽灵 PID。即使应用程序“关闭”,但 PID 仍然存在,所以我做了 PID 的 jmap 当 jmap 没有告诉我任何关于幽灵资源的建议时,我尝试了 jstack 的 pid。

我看到这个资源挂起(或类似),简而言之,它卡在 LinkedBlockingqueue.take() 上。

"pool-17-thread-1" #50 prio=5 os_prio=64 tid=0x0000000101758000 nid=0x5f waiting on condition [0xffffffff3f4fe000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007bf948000> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

我注意到,同一个堆栈的条目数量与我所做的测试(请求)数量一样多。

我有一些自己的 LinkedBlockingQueues,所以我删除了 take() 以使用 stackoverflow 上的答案进行轮询(我现在找不到链接)。但它不是我们的。所以我怀疑restEasy在下面使用了LBQueue。调试只会向我显示一个可以执行此操作的线程,但不会告诉我它从哪里启动。

我在 stackoverflow 上阅读过,在一些 Resteasy 邮件组中也有这个问题,但没有解决方案。我尝试改变我的方法,并在阅读了 RestEasyClient 父级的 javadoc 后得出结论

Clients are heavy-weight objects that manage the client-side communication infrastructure. Initialization as well as disposal of a {@code Client} instance may be a rather expensive operation. It is therefore advised to construct only a small number of {@code Client} instances in the application. Client instances must be {@link

close() properly closed before being disposed to avoid leaking resources.

(应该阅读我开始使用的内容)所以我改变了我的实现,只创建一个客户端和多个 client.targets

 ResteasyWebTarget resteasyWebTarget = client.target(url);

这消除了资源泄漏。从技术上讲,JS RX 或 Resteasy 中不存在资源泄漏,只是它的实现方式不同。希望这可以帮助那些可能犯了与我相同的错误并且对不会消亡的资源感到困惑的人。

一些非常好的帖子可以帮助和进一步完善它: Memory issue with JAX RS using jersey

我认为这两个答案都非常有值(value)

关于java - 如果未正确完成 RestEasyClient JAX RS 可能会出现资源泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51831789/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com