我有一个使用嵌入式Jetty(版本9.3.6.v20151106)和JDK 8u65的应用程序。
当我在Mac或Linux上使用此应用程序时,我没有遇到任何困难。但是在Windows上,Jetty无法启动,应用程序将永久挂起。
我在进程上运行了一个jstack命令并隔离了阻止服务器启动的线程。
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x1a3b2018> (a java.util.concurrent.Semaphore$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
at java.util.concurrent.Semaphore.acquire(Semaphore.java:312)
at org.eclipse.jetty.annotations.AnnotationConfiguration.scanForAnnotations(AnnotationConfiguration.java:540)
at org.eclipse.jetty.annotations.AnnotationConfiguration.configure(AnnotationConfiguration.java:447)
at org.eclipse.jetty.webapp.WebAppContext.configure(WebAppContext.java:491)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1336)
我找了另一个阻止锁的线程,但没有。
如何进一步调试此问题?它是JVM错误还是Windows安全功能?非常感谢任何帮助。
答案 0 :(得分:1)
Windows似乎无法正确报告处理器数量。 尝试将org.eclipse.jetty.annotations.multiThreaded属性设置为false,看看是否有帮助。
答案 1 :(得分:1)
事实证明我对自己的日志视而不见。我发现在扫描应用程序的jar时我正在抛出OOM。 有很多因素可以解释为什么这种情况会在Windows上发生。首先,这是一个32位发行版,所以它在内存方面有点反复无常。 Java的最大堆大小最终会受到影响。
正如在#jetty IRC频道上所讨论的那样(由于他的精彩帮助而得到joakime的称赞和赞誉),这是由于jar扫描应用程序的WEB-INF / lib。这会增加启动时间,如果你有大量的垃圾文件罐,可能会导致OOM。
joakime指出了解决问题的两种可能性:
我最终使用了后者。我使用这个正则表达式匹配jstl jar和spring jar(我使用springl的jarlibs jar):
".*/jstl-[^/]*\\.jar$|.*/spring-[^/]*\\.jar$"
答案 2 :(得分:0)
我找了另一个阻止锁的线程,但没有。
信号量比锁更通用。这是一堆许可,不一定与任何瘦身有关。它们可以由一个或多个线程获取和释放,并且不需要在已完成获取的线程上发布。
一个线程甚至可以创建一个信号量,消耗所有可用的许可,然后等待它自己的信号量而没有另一个线程接触它。
因此,通过查找“持有锁”的其他线程,无法轻松完成调试信号量。
要调试它们,您必须跟踪获取和发布,并查看许可证耗尽的位置,然后找出它们应该被释放的位置,但不是。