Tomcat webapp 错误 - 应用程序启动线程 [AWT-Windows] 但未能阻止它 - 内存泄漏?

Posted

技术标签:

【中文标题】Tomcat webapp 错误 - 应用程序启动线程 [AWT-Windows] 但未能阻止它 - 内存泄漏?【英文标题】:Tomcat webapp error - application started thread [AWT-Windows] but has failed to stop it - memory leak? 【发布时间】:2011-05-18 16:32:31 【问题描述】:

直到今天在我的电脑上进行一些本地测试时,我才注意到 Tomcat 在日志文件中发布了一个错误。我正在使用 Tomcat 6.0.29 和 Java JDK 1.6。

Dec 1, 2010 12:36:57 pm org.apache.catalina.core.StandardContext reload INFO: Reloading this Context has started Dec 1, 2010 12:36:57 pm org.apache.catalina.loader.WebappClassLoader clearReferencesThreads SEVER: The web application [/AutoSpyder] appears to have started a thread named [AWT-Windows] but has failed to stop it. This is very likely to create a memory leak.

什么?我以前从未见过这种情况。所以我检查了我昨天的日志文件,果然,这个错误也在那里。我不太明白这是什么原因造成的。

我可以假设它必须是我的一个使用 java.awt 包中的对象的 servlet 吗? 如果是这样,我如何查明导致这种情况的代码?

编辑添加线程转储

2010-12-01 14:28:18 全线程转储 Java HotSpot(TM) Client VM(17.1-b03 混合模式,共享): “JMX 服务器连接超时 34”守护进程 prio=6 tid=0x03069400 nid=0x960 in Object.wait() [0x0461f000] java.lang.Thread.State:TIMED_WAITING(在对象监视器上) 在 java.lang.Object.wait(本机方法) - 等待 (a [I) 在 com.sun.jmx.remote.internal.ServerCommunicatorAdmin$Timeout.run(ServerCommunicatorAdmin.java:150) - 锁定(a [I) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: - 没有 “RMI Scheduler(0)”守护进程prio=6 tid=0x03069000 nid=0xe88等待条件[0x045cf000] java.lang.Thread.State:TIMED_WAITING(停车) 在 sun.misc.Unsafe.park(本机方法) - 停车等待(java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) 在 java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198) 在 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025) 在 java.util.concurrent.DelayQueue.take(DelayQueue.java:164) 在 java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:609) 在 java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:602) 在 java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:947) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: - 没有 “RMI TCP 连接 (1)-192.168.0.102”守护进程 prio=6 tid=0x0308a400 nid=0xebc 可运行 [0x0457f000] java.lang.Thread.State:可运行 在 java.net.SocketInputStream.socketRead0(本机方法) 在 java.net.SocketInputStream.read(SocketInputStream.java:129) 在 java.io.BufferedInputStream.fill(BufferedInputStream.java:218) 在 java.io.BufferedInputStream.read(BufferedInputStream.java:237) - 锁定(一个 java.io.BufferedInputStream) 在 java.io.FilterInputStream.read(FilterInputStream.java:66) 在 sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:517) 在 sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790) 在 sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649) 在 java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: -(一个 java.util.concurrent.locks.ReentrantLock$NonfairSync) “RMI TCP Accept-0”守护进程prio=6 tid=0x039e0c00 nid=0xc68 可运行[0x0452f000] java.lang.Thread.State:可运行 在 java.net.PlainSocketImpl.socketAccept(本机方法) 在 java.net.PlainSocketImpl.accept(PlainSocketImpl.java:390) - 锁定(一个 java.net.SocksSocketImpl) 在 java.net.ServerSocket.implAccept(ServerSocket.java:453) 在 java.net.ServerSocket.accept(ServerSocket.java:421) 在 sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:34) 在 sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:369) 在 sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:341) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: - 没有 “AWT-Windows”守护进程prio=6 tid=0x02b65400 nid=0x7c4 可运行[0x042cf000] java.lang.Thread.State:可运行 在 sun.awt.windows.WToolkit.eventLoop(本机方法) 在 sun.awt.windows.WToolkit.run(WToolkit.java:293) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: - 没有 “Java2D Disposer”守护进程 prio=10 tid=0x02fccc00 nid=0x93c in Object.wait() [0x039df000] java.lang.Thread.State:等待(在对象监视器上) 在 java.lang.Object.wait(本机方法) - 等待(java.lang.ref.ReferenceQueue$Lock) 在 java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118) - 锁定(java.lang.ref.ReferenceQueue$Lock) 在 java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134) 在 sun.java2d.Disposer.run(Disposer.java:127) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: - 没有 “http-8080-6”守护进程prio=6 tid=0x03322800 nid=0xfec in Object.wait() [0x0395f000] java.lang.Thread.State:等待(在对象监视器上) 在 java.lang.Object.wait(本机方法) - 等待(org.apache.tomcat.util.net.JIoEndpoint$Worker) 在 java.lang.Object.wait(Object.java:485) 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:458) - 锁定(一个 org.apache.tomcat.util.net.JIoEndpoint$Worker) 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:484) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: - 没有 “http-8080-5”守护进程prio=6 tid=0x02ba5c00 nid=0xdbc in Object.wait() [0x0390f000] java.lang.Thread.State:等待(在对象监视器上) 在 java.lang.Object.wait(本机方法) - 等待(org.apache.tomcat.util.net.JIoEndpoint$Worker) 在 java.lang.Object.wait(Object.java:485) 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:458) - 锁定(一个 org.apache.tomcat.util.net.JIoEndpoint$Worker) 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:484) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: - 没有 “http-8080-4”守护进程prio=6 tid=0x02ff6400 nid=0xa1c in Object.wait() [0x038bf000] java.lang.Thread.State:等待(在对象监视器上) 在 java.lang.Object.wait(本机方法) - 等待(org.apache.tomcat.util.net.JIoEndpoint$Worker) 在 java.lang.Object.wait(Object.java:485) 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:458) - 锁定(一个 org.apache.tomcat.util.net.JIoEndpoint$Worker) 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:484) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: - 没有 “http-8080-3”守护进程prio=6 tid=0x0317e400 nid=0x850 in Object.wait() [0x0386f000] java.lang.Thread.State:等待(在对象监视器上) 在 java.lang.Object.wait(本机方法) - 等待(org.apache.tomcat.util.net.JIoEndpoint$Worker) 在 java.lang.Object.wait(Object.java:485) 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:458) - 锁定(一个 org.apache.tomcat.util.net.JIoEndpoint$Worker) 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:484) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: - 没有 “http-8080-2”守护进程prio=6 tid=0x03314800 nid=0xf9c in Object.wait() [0x0381f000] java.lang.Thread.State:等待(在对象监视器上) 在 java.lang.Object.wait(本机方法) - 等待(org.apache.tomcat.util.net.JIoEndpoint$Worker) 在 java.lang.Object.wait(Object.java:485) 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:458) - 锁定(一个 org.apache.tomcat.util.net.JIoEndpoint$Worker) 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:484) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: - 没有 “http-8080-1”守护进程prio=6 tid=0x02efe800 nid=0x250 in Object.wait() [0x037cf000] java.lang.Thread.State:等待(在对象监视器上) 在 java.lang.Object.wait(本机方法) - 等待(org.apache.tomcat.util.net.JIoEndpoint$Worker) 在 java.lang.Object.wait(Object.java:485) 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:458) - 锁定(一个 org.apache.tomcat.util.net.JIoEndpoint$Worker) 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:484) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: - 没有 “TP-Monitor”守护进程 prio=6 tid=0x02eed800 nid=0xd64 in Object.wait() [0x0375f000] java.lang.Thread.State:TIMED_WAITING(在对象监视器上) 在 java.lang.Object.wait(本机方法) - 等待(org.apache.tomcat.util.threads.ThreadPool$MonitorRunnable) 在 org.apache.tomcat.util.threads.ThreadPool$MonitorRunnable.run(ThreadPool.java:565) - 锁定(一个 org.apache.tomcat.util.threads.ThreadPool$MonitorRunnable) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: - 没有 “TP-Processor4”守护进程prio=6 tid=0x0318b000 nid=0x998 可运行[0x0370f000] java.lang.Thread.State:可运行 在 java.net.PlainSocketImpl.socketAccept(本机方法) 在 java.net.PlainSocketImpl.accept(PlainSocketImpl.java:390) - 锁定(一个 java.net.SocksSocketImpl) 在 java.net.ServerSocket.implAccept(ServerSocket.java:453) 在 java.net.ServerSocket.accept(ServerSocket.java:421) 在 org.apache.jk.common.ChannelSocket.accept(ChannelSocket.java:312) 在 org.apache.jk.common.ChannelSocket.acceptConnections(ChannelSocket.java:666) 在 org.apache.jk.common.ChannelSocket$SocketAcceptor.runIt(ChannelSocket.java:877) 在 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: - 没有 “TP-Processor3”守护进程prio=6 tid=0x0308f800 nid=0x92c in Object.wait() [0x036bf000] java.lang.Thread.State:等待(在对象监视器上) 在 java.lang.Object.wait(本机方法) - 等待(一个 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable) 在 java.lang.Object.wait(Object.java:485) 在 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:662) - 锁定(一个 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: - 没有 “TP-Processor2”守护进程prio=6 tid=0x03192400 nid=0xfac in Object.wait() [0x0366f000] java.lang.Thread.State:等待(在对象监视器上) 在 java.lang.Object.wait(本机方法) - 等待(一个 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable) 在 java.lang.Object.wait(Object.java:485) 在 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:662) - 锁定(一个 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: - 没有 “TP-Processor1”守护进程prio=6 tid=0x03182400 nid=0x8d8 in Object.wait() [0x0361f000] java.lang.Thread.State:等待(在对象监视器上) 在 java.lang.Object.wait(本机方法) - 等待(一个 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable) 在 java.lang.Object.wait(Object.java:485) 在 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:662) - 锁定(一个 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: - 没有 “http-8080-Acceptor-0”守护进程prio=6 tid=0x03172400 nid=0xf04 可运行[0x035cf000] java.lang.Thread.State:可运行 在 java.net.PlainSocketImpl.socketAccept(本机方法) 在 java.net.PlainSocketImpl.accept(PlainSocketImpl.java:390) - 锁定(一个 java.net.SocksSocketImpl) 在 java.net.ServerSocket.implAccept(ServerSocket.java:453) 在 java.net.ServerSocket.accept(ServerSocket.java:421) 在 org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:61) 在 org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:352) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: - 没有 “ContainerBackgroundProcessor[StandardEngine[Catalina]]”守护进程prio=6 tid=0x03163400 nid=0xbe8等待条件[0x0357f000] java.lang.Thread.State: TIMED_WAITING (睡眠) 在 java.lang.Thread.sleep(本机方法) 在 org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1579) 在 java.lang.Thread.run(Thread.java:662) 锁定的可拥有同步器: - 没有 “GC 守护进程”守护进程 prio=2 tid=0x0307bc00 nid=0x110 in Object.wait() [0x0349f000] java.lang.Thread.State:TIMED_WAITING(在对象监视器上) 在 java.lang.Object.wait(本机方法) - 等待(sun.misc.GC$LatencyLock) 在 sun.misc.GC$Daemon.run(GC.java:100) - 锁定(sun.misc.GC$LatencyLock) 锁定的可拥有同步器: - 没有 “内存不足检测器”守护进程 prio=6 tid=0x02aecc00 nid=0x5b4 可运行 [0x00000000] java.lang.Thread.State:可运行 锁定的可拥有同步器: - 没有 “CompilerThread0”守护进程prio=10 tid=0x02ae7000 nid=0x798 等待条件[0x00000000] java.lang.Thread.State:可运行 锁定的可拥有同步器: - 没有 “附加侦听器”守护进程 prio=10 tid=0x02ae5800 nid=0xddc 等待条件 [0x00000000] java.lang.Thread.State:可运行 锁定的可拥有同步器: - 没有 “信号调度程序”守护进程 prio=10 tid=0x02ae4000 nid=0xc00 可运行 [0x00000000] java.lang.Thread.State:可运行 锁定的可拥有同步器: - 没有 “终结器”守护进程 prio=8 tid=0x02add400 nid=0x378 in Object.wait() [0x02caf000] java.lang.Thread.State:等待(在对象监视器上) 在 java.lang.Object.wait(本机方法) - 等待(java.lang.ref.ReferenceQueue$Lock) 在 java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118) - 锁定(java.lang.ref.ReferenceQueue$Lock) 在 java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134) 在 java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159) 锁定的可拥有同步器: - 没有 Object.wait() [0x02c5f000] 中的“引用处理程序”守护进程 prio=10 tid=0x02adbc00 nid=0x474 java.lang.Thread.State:等待(在对象监视器上) 在 java.lang.Object.wait(本机方法) - 等待(java.lang.ref.Reference$Lock) 在 java.lang.Object.wait(Object.java:485) 在 java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116) - 锁定(java.lang.ref.Reference$Lock) 锁定的可拥有同步器: - 没有 “主要”prio=6 tid=0x002b7000 nid=0x14c 可运行 [0x0090f000] java.lang.Thread.State:可运行 在 java.net.PlainSocketImpl.socketAccept(本机方法) 在 java.net.PlainSocketImpl.accept(PlainSocketImpl.java:390) - 锁定(一个 java.net.SocksSocketImpl) 在 java.net.ServerSocket.implAccept(ServerSocket.java:453) 在 java.net.ServerSocket.accept(ServerSocket.java:421) 在 org.apache.catalina.core.StandardServer.await(StandardServer.java:389) 在 org.apache.catalina.startup.Catalina.await(Catalina.java:662) 在 org.apache.catalina.startup.Catalina.start(Catalina.java:614) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在 java.lang.reflect.Method.invoke(Method.java:597) 在 org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289) 在 org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414) 锁定的可拥有同步器: - 没有 “VM 线程”prio=10 tid=0x02ada400 nid=0x210 可运行 “VM 定期任务线程”prio=10 tid=0x02aefc00 nid=0x79c 等待条件 JNI 全局引用:1529

【问题讨论】:

【参考方案1】:

尝试进行线程转储以获取服务器上运行的所有线程的列表。由此,您也许可以根据堆栈跟踪准确确定哪个类启动了线程

窗口

在控制台窗口上按ctrl + break

Unix

在命令行中输入:kill -3 <pid>

【讨论】:

我使用 VisualVM 进行线程转储 - 我找到了一个“AWT-Windows”条目,它记录了以下内容:“AWT-Windows”守护进程 prio=6 tid=0x02b65400 nid=0x7c4 runnable [0x042cf000] java.lang.Thread.State: RUNNABLE 在 sun.awt.windows.WToolkit.eventLoop(Native Method) 在 sun.awt.windows.WToolkit.run(WToolkit.java:293) 在 java.lang.Thread。 run(Thread.java:662) 锁定可拥有同步器:- 无 我不是专家,所以对我来说太赤裸裸了:) 我没有在我的类中使用任何 WToolKit 对象......那么为什么会弹出这个错误?它是否与我正在通过我的电脑上的“localhost”tomcat 服务器运行/测试我的 web 应用程序这一事实直接相关? 您能否将完整主题作为对您答案的编辑。会让那里更容易阅读 同样在 VisualVM 中,如果您在几天内监控您的应用程序,您的堆看起来如何? 您的线程转储看起来确实很干净,如果您没有遇到任何重大内存问题,我认为您的应用程序会很好。您在日志中找到的消息是 INFO,因此它不是错误或致命异常。如果您还没有这样做,请使用 JMeter 等应用程序对您的应用程序进行负载测试,并使用 VisualVM,您可以分析在实际负载下您的应用程序会发生什么。同样在 Tomcat 中,确保设置 -XX:+HeapDumpOnOutOfMemoryError 标志。这样,如果您确实遇到内存问题,您将有一个良好的分析起点【参考方案2】:

这与 Windows(即 MS Windows)和对底层操作系统的本机调用有关。这些通常是 GUI 类型的窗口操作,但也可能是其他特定于操作系统的东西,例如剪贴板或与字体相关的东西。

如果您在代码中看不到任何明显可能与触发它的原因有关的内容,但我不会担心 - 该警告更适用于在网络应用程序中分离新线程的一般情况在没有充分了解潜在问题的情况下,您不应该明确地这样做。

【讨论】:

当我看到这个错误时,我担心当 webapp 实时运行时它会出现在我的 vps 上。我只有 1 个使用 java.awt 类的 servlet/类,其目的是从 db 表中上传/检索图像(实际图像为字节)......所以我想也许那个类是这个错误的触发器.但是你很确定这个错误更多的是因为我在我的本地电脑上运行我的应用程序......并且触发器与 Windows 相关?【参考方案3】:

我们有tomcat服务器和jsf。 JSF 客户端将从服务器请求图像并启动 AWT-Windows 线程。似乎会导致内存泄漏,因为线程 contextClassLoader 是 WebappClassLoader。

看起来调用 Java2DResource 会导致创建 AWT-Windows 线程 -

守护线程 [http-8080-1](暂停(进入线程中的方法)) Thread.(Runnable, String) line: 444 NativeConstructorAccessorImpl.newInstance(Object[]) 行:39 DelegatingConstructorAccessorImpl.newInstance(Object[]) 行:27 Constructor.newInstance(Object...) 行:513 Class.newInstance0() 行:355 Class.newInstance() 行:308 Toolkit$2.run() 行:846 AccessController.doPrivileged(PrivilegedAction) 行:不可用 [本机方法] Toolkit.getDefaultToolkit() 行:826 D3DGraphicsDevice.() 行:47 SurfaceManagerFactory.createCachingManager(BufferedImage) 行:48 SurfaceManager.getManager(Image) 行:54 SurfaceData.getDestSurfaceData(Image) 行:123 Win32GraphicsEnvironment(SunGraphicsEnvironment).createGraphics(BufferedImage) 行:389 HeadlessGraphicsEnvironment.createGraphics(BufferedImage) 行:76 BufferedImage.createGraphics() 行:1137 TabStripeImage(Java2Dresource).getImage(ResourceContext) 行:115 TabStripeImage(Java2Dresource).send(ResourceContext) 行:89 ResourceLifecycle.sendResource(ResourceContext, InternetResource) 行:219 ResourceLifecycle.send(ResourceContext, InternetResource) 行:158 InternetResourceService.load(Object, Object) 行:335 LRUMapCache.load(Object, Object) 行:116 LRUMapCache.get(Object, Object) 行:87 InternetResourceService.serviceResource(String, HttpServletRequest, HttpServletResponse) 行:195 InternetResourceService.serviceResource(HttpServletRequest, HttpServletResponse) 行:141 Filter(BaseFilter).doFilter(ServletRequest, ServletResponse, FilterChain) 行:508 Ajax4jsfFilter.doFilter(ServletRequest, ServletResponse, FilterChain) 行:56 SeamFilter$FilterChainImpl.doFilter(ServletRequest, ServletResponse) 行:69 LoggingFilter.doFilter(ServletRequest, ServletResponse, FilterChain) 行:60 SeamFilter$FilterChainImpl.doFilter(ServletRequest, ServletResponse) 行:69 SeamFilter.doFilter(ServletRequest, ServletResponse, FilterChain) 行:158 ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) 行:235 ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) 行:206 StandardWrapperValve.invoke(请求,响应)行:233 StandardContextValve.invoke(Request, Response) 行:191 StandardHostValve.invoke(Request, Response) 行:127 ErrorReportValve.invoke(Request, Response) 行:102 AccessLogValve.invoke(请求,响应)行:555 StandardEngineValve.invoke(请求,响应)行:109 CoyoteAdapter.service(请求,响应)行:298 Http11AprProcessor.process(long) 行:861 Http11AprProtocol$Http11ConnectionHandler.process(long) 行:579 AprEndpoint$Worker.run() 行:1584 Thread.run() 行:619 [局部变量不可用]

【讨论】:

这对我和我的情况意味着什么?我之前没有在 tomcat 日志中看到有关 AWT 警告的条目。我从 java.awt 中使用的唯一类如下: java.awt.geom.AffineTransform; java.awt.image.BufferedImage; java.awt.RenderingHints; java.awt.Graphics2D; java.awt.Image 我得到的错误是指 sun.awt.windows.WToolkit.eventLoop(Native Method) sun.awt.windows.WToolkit.run(WToolkit.java:293) 那么我可以假设它有什么用我的本地电脑做,因为它似乎没有发生在我的远程 vps 上?【参考方案4】:

看起来您正在运行 JMX,而我的印象是 Tomcat JMX 服务器可能是实际设置计时器线程的原因。除了您在 JavaRanch 上的并行帖子中提到的那些之外,您在此处的转储中还有一个 java2D 线程。

我无法确定 100%,因为我不知道哪些线程是孤儿线程的父线程。如果您能确定这一点,那将有所帮助。

但是,您的仿射变换肯定会引入图形。这是一个图形功能,它将尝试将您的视频卡用作硬件加速器。如果您不指定无头操作,它将利用您的窗口系统来执行此操作。

【讨论】:

我收到此错误,我一直在生产服务器上运行 JMX。在生产服务器上启动 Tomcat/TomEE 时,最好从我的 JVM 选项中删除 JMX 选项。【参考方案5】:

受this thread启发,我找到了以下解决方案:

您只需要将 AWT-Window-Thread 附加到 System-Classloader 而不是 Wabapp-Classloader。您可以像这样在 ServletContextListener 中执行此操作:

public void contextInitialized(ServletContextEvent evt) 
    Thread thread = Thread.currentThread();
    ClassLoader ccl = thread.getContextClassLoader(); // PUSH
    try 
        thread.setContextClassLoader(ClassLoader.getSystemClassLoader());
        Toolkit.getDefaultToolkit().createImage(new byte[]);
     finally 
        thread.setContextClassLoader(ccl); // POP
    

【讨论】:

我不会这样做。将上下文设置为系统类加载器使得无法在 Tomcat 等 servlet 容器中正确重新加载应用程序。【参考方案6】:

您是否正在运行包含可能与 AWT 交互的 Jasper、JFreechart、LiquidOffice、StyleReport 等某种图形库?

尝试通过提供 -Djava.awt.headless=true 属性来启动 tomcat 以查看是否消除了异常

【讨论】:

不,不运行任何类型的图形库。至于使用 java.awt 包中的任何类,我在 1 个 servlet 中使用的唯一类如下:java.awt.geom.AffineTransform、java.awt.image.BufferedImage、java.awt.RenderingHints、java.awt .Graphics2D, java.awt.Image 本地,我通过dos提示启动tomcat。所以我做了'startup -Djava.awt.headless=true' - 我假设这有效,因为启动时没有任何错误。我注意到的唯一一件事是“用法:java org.apache.catalina.startup.Catalina [ -config pathname ] [ -nonaming ] 在tomcat启动之前的输出顶部......

以上是关于Tomcat webapp 错误 - 应用程序启动线程 [AWT-Windows] 但未能阻止它 - 内存泄漏?的主要内容,如果未能解决你的问题,请参考以下文章

Docker方式启动tomcat,访问首页出现404错误

Apache Tomcat/6.0.32 - Web 应用程序无法启动

tomcat不编译webapps下的war包的解决办法

Tomcat正常启动,可以访问tomcat主页,却不能访问webapp中的项目的jsp文件,这是啥原因?

Tomcat能正常启动,可以访问tomcat主页,却在eclipse中不能访问webapp中的项目的jsp文件,这是啥原因?

如何从 Windows .bat 启动 Tomcat webapp