Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tomcat容器运行,存在内存泄漏风险 #398

Open
yuhao0926 opened this issue Dec 3, 2020 · 6 comments
Open

tomcat容器运行,存在内存泄漏风险 #398

yuhao0926 opened this issue Dec 3, 2020 · 6 comments
Assignees
Labels
bug Something isn't working

Comments

@yuhao0926
Copy link

Describe the bug

场景:
spring应用引用了sofa tracer的springmvn+zipkin两个依赖,进行链路监控
操作:
当spring应用运行在tomcat容器中时,直接对应用redeploy
结果:
tomcat的线程清理(WebappClassLoaderBase.clearReferencesThreads)发现相关线程无法被收回
发现日志后,通过对jvm线程监控,tomcat容器不动,应用多次redeploy,相关线程的确会重复创建,且无法gc回收
···

相关日志
03-Dec-2020 09:55:37.776 警告 [RMI TCP Connection(13)-127.0.0.1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads Web应用程序[brave-webmvc-example]似乎启动了一个名为[Tracer-AsyncConsumer-Thread-SelfLogAppender]的线程,但未能停止它。这很可能会造成内存泄漏。线程的堆栈跟踪:[
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
com.alipay.disruptor.BlockingWaitStrategy.waitFor(BlockingWaitStrategy.java:40)
com.alipay.disruptor.ProcessingSequenceBarrier.waitFor(ProcessingSequenceBarrier.java:47)
com.alipay.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:110)
java.lang.Thread.run(Thread.java:748)]
03-Dec-2020 09:55:37.776 警告 [RMI TCP Connection(13)-127.0.0.1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads Web应用程序[brave-webmvc-example]似乎启动了一个名为[Tracer-TimedAppender-1-60]的线程,但未能停止它。这很可能会造成内存泄漏。线程的堆栈跟踪:[
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
java.lang.Thread.run(Thread.java:748)]
03-Dec-2020 09:55:37.777 警告 [RMI TCP Connection(13)-127.0.0.1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads Web应用程序[brave-webmvc-example]似乎启动了一个名为[Tracer-AsyncConsumer-Thread-NetworkAppender]的线程,但未能停止它。这很可能会造成内存泄漏。线程的堆栈跟踪:[
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
com.alipay.disruptor.BlockingWaitStrategy.waitFor(BlockingWaitStrategy.java:40)
com.alipay.disruptor.ProcessingSequenceBarrier.waitFor(ProcessingSequenceBarrier.java:47)
com.alipay.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:110)
java.lang.Thread.run(Thread.java:748)]
···

Expected behavior

不存在内存泄漏,线程正常结束

Actual behavior

存在内存泄漏,线程重复创建且无法回收

Steps to reproduce

tomcat启动web应用,且应用引用了springmvc tracer
tomcat容器不动,重复对应用redeploy

Environment

  • SOFATracer version:
  • JVM version 8
  • Tomcat version 8.5.6
  • sofa-tracer version: 2.3.0
@ujjboy
Copy link
Member

ujjboy commented Dec 3, 2020

这个线程是单例,应该没有问题的。

你 jstack 确认下 redeploy 之后 Tracer-AsyncConsumer-Thread-SelfLogAppender 线程有多个吗?如果只有一个的话,那就没问题。

@yuhao0926
Copy link
Author

这个线程是单例,应该没有问题的。

你 jstack 确认下 redeploy 之后 Tracer-AsyncConsumer-Thread-SelfLogAppender 线程有多个吗?如果只有一个的话,那就没问题。

通过jvm监控,已经确认有这种情况

image

@ujjboy ujjboy added the bug Something isn't working label Dec 3, 2020
@ujjboy
Copy link
Member

ujjboy commented Dec 3, 2020

好的,那就说明有问题。 你的 redeploy 是怎么操作的,复现方法有不?

@yuhao0926
Copy link
Author

好的,那就说明有问题。 你的 redeploy 是怎么操作的,复现方法有不?

可以通过本地测试复现
(1)本地使用idea运行tomcat容器,且运行应用
(2)正常进行tracer监控测试,确保tracer线程运行
(3)使用idea的redeploy按钮,或者执行对应命令
(4)jvm监控即可复现

image

@ujjboy
Copy link
Member

ujjboy commented Dec 3, 2020

@yuhao0926 场景收到,这种直接部署war,不同 classloader的 case 我们看一下。

@yuhao0926
Copy link
Author

@yuhao0926 场景收到,这种直接部署war,不同 classloader的 case 我们看一下。

好的谢谢,这种情况在我理解,可能类似log4j,mysql-conn这种情况,它们是提供了一个手动clear的shutdown方法,这样在类似不同classloader的情况下,可以进行线程安全控制,例如tomcat可以通过注册ServletContextListener的contextDestroyed方法进行一些销毁操作。。不知道sofa-tracer是否原理相同

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants