我已经在JProfiler和VisualVM中浏览了Play 2.3.4应用程序的几个堆快照(具有讽刺意味的是VisualVM似乎更有帮助),并且发现了Play!重新加载类加载器没有被正确替换,并且保留旧类的旧实例的旧类加载器的几个副本保留在内存中。在几次应用程序重新加载后,应用程序崩溃并出现内存不足错误(堆积在永久生成之前一直耗尽,可能是由于应用程序的内存密集型特性)。
在跟踪GC根源时,我发现了以下隐含的证据。使用活动对象有4个 PlayRun $$ anonfun $ 10 $$ anon $ 2 的实例,据我所知,应该只有1个特别注意到这些类加载器实例中的每一个都包含重复的副本我的应用程序的类:
通过线程堆栈帧保留在内存中的4 PlayRun $$ anonfun $ 10 $$ anon $ 2 实例的GC根源:为什么这些其他线程会保留对过时Play的引用!应用程序类加载器?不玩!关闭这样的依赖线程来防止这种情况?重新加载过程的某些阶段是否可能无法正确执行导致此不良对象保留状态?
该应用程序建立在Play之上! 2.3.4和SBT 0.13.6。在从Play升级之前,没有发生此问题! 2.2.2 / SBT 0.13.1。