2

我正在使用 Spring 开发一个 Web 应用程序,但我遇到了这个奇怪的错误。我不知道它来自哪里,我一直在用谷歌搜索,到目前为止一无所获。

在我正在使用的项目中:MongoDB、Spring、WSS4J(soap 的 X.509 安全标头)、Apache CXF。我一直在尝试发现是否有导致此错误的原因,任何特定的动作,行为,条件,但到目前为止我什么也没发现,有时会在运行 3 分钟后发生,有时会在 3 小时后发生,或者根本没有,任何线索和提示赞赏。

INFO: Illegal access: this web application instance has been stopped already.  Could not load net.sf.ehcache.store.disk.Segment$1.  The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
java.lang.IllegalStateException
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1597)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556)
    at net.sf.ehcache.store.disk.Segment$HashIterator.<init>(Segment.java:988)
    at net.sf.ehcache.store.disk.Segment.hashIterator(Segment.java:936)
    at net.sf.ehcache.store.disk.DiskStore$HashIterator.<init>(DiskStore.java:1038)
    at net.sf.ehcache.store.disk.DiskStore$KeyIterator.<init>(DiskStore.java:1111)
    at net.sf.ehcache.store.disk.DiskStore$KeyIterator.<init>(DiskStore.java:1111)
    at net.sf.ehcache.store.disk.DiskStore$KeySet.iterator(DiskStore.java:949)
    at net.sf.ehcache.store.disk.DiskStorageFactory$DiskExpiryTask.run(DiskStorageFactory.java:838)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:351)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)`
4

1 回答 1

1

这意味着 ehcache 线程在应用程序停止或重新部署后尝试与应用程序交互。仅当 ehcache 达到您在 ehcache.xml 中的限制并试图溢出到磁盘时才会发生这种情况。

停止应用程序时查看 tomcat 日志以获取警告:

严重:Web 应用程序 [/APP] 似乎已经启动了一个名为 [Ehcache_Worker-1] 的线程,但未能停止它。这很可能造成内存泄漏

如果发现这样的东西,你应该在你的 ServletContextListener 中正确地停止 ecache:

public void contextDestroyed(ServletContextEvent servletContextEvent){
      CacheManager.getInstance().shutdown();
}

之后可能会休眠 1 秒,以确保停止 ehcache。

http://ehcache.org/documentation/faq中所述

如果停止使用 Ehcache 后 JVM 继续运行,则应调用 CacheManager.getInstance().shutdown() 以便停止线程并将缓存内存释放回 JVM。调用 shutdown 还可以确保您的永久磁盘存储以一致的状态写入磁盘,并且在下次使用时可用。如果 CacheManager 没有关闭,那应该不是问题。有一个关闭钩子,它在 JVM 退出时调用关闭。

或者您可以overflowToDisk="false"在 ehcache.xml 中设置属性或在每次部署应用程序时重新启动 tomcat。

于 2012-08-09T13:26:38.127 回答