尝试检测webapp中的内存泄漏。
解析的整理信息导致了这两个结论 -
这是否意味着没有发生泄漏?并且由于内存不足错误而发生崩溃?
编辑:添加ENV信息
添加最大对象的传入参考列表 -
这里的每个哈希映射实例都有一个来自com.opensymphony.xwork2的引用,它不是GC收集的。这可能是问题的根源。因为tomcat日志说 -
SEVERE: The web application [/openreports] created a ThreadLocal with key of type [com.opensymphony.xwork2.ActionContext.ActionContextThreadLocal] (value [com.opensymphony.xwork2.ActionContext$ActionContextThreadLocal@7c45901a]) and a value of type [com.opensymphony.xwork2.ActionContext] (value [com.opensymphony.xwork2.ActionContext@3af7dab3]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
SEVERE: The web application [/openreports] created a ThreadLocal with key of type [com.opensymphony.xwork2.inject.ContainerImpl$10] (value [com.opensymphony.xwork2.inject.ContainerImpl$10@258c27bd]) and a value of type [com.opensymphony.xwork2.inject.InternalContext[]] (value [[Lcom.opensymphony.xwork2.inject.InternalContext;@1484fc8d]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
编辑:添加OOM错误的堆栈跟踪
java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Arrays.java:3209)
at java.lang.String.<init>(String.java:215)
at java.lang.StringBuffer.toString(StringBuffer.java:585)
at java.io.StringWriter.toString(StringWriter.java:193)
at org.displaytag.tags.TableTag.writeExport(TableTag.java:1503)
at org.displaytag.tags.TableTag.doExport(TableTag.java:1454)
at org.displaytag.tags.TableTag.doEndTag(TableTag.java:1309)
at org.efs.openreports.engine.QueryReportEngine.generateReport(QueryReportEngine.java:198)
at org.efs.openreports.util.ScheduledReportJob.execute(ScheduledReportJob.java:173)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:529)
10:01:04,193 ERROR ErrorLogger - Job (90.70|1338960412084 threw an exception.
org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: java.lang.OutOfMemoryError: Java heap space]
at org.quartz.core.JobRunShell.run(JobRunShell.java:213)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:529)
Caused by: java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Arrays.java:3209)
at java.lang.String.<init>(String.java:215)
at java.lang.StringBuffer.toString(StringBuffer.java:585)
at java.io.StringWriter.toString(StringWriter.java:193)
at org.displaytag.tags.TableTag.writeExport(TableTag.java:1503)
at org.displaytag.tags.TableTag.doExport(TableTag.java:1454)
at org.displaytag.tags.TableTag.doEndTag(TableTag.java:1309)
at org.efs.openreports.engine.QueryReportEngine.generateReport(QueryReportEngine.java:198)
at org.efs.openreports.util.ScheduledReportJob.execute(ScheduledReportJob.java:173)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
答案 0 :(得分:0)
您运行的是ASP.NET WebForms(而不是MVC)应用程序吗?我们的应用程序中存在类似的问题,这些是我们遇到的问题。首先,我应该声明我们的Web场由许多应用程序池组成,当然每个客户端都有一个应用程序池。每个应用程序池都有一个特定的内存限制,以确保客户端不会使内存失控并影响其他工作进程。
1)即使对象没有生根,如果它们超过85K,它们也会被放置在大型对象堆上,而.NET的GC不能压缩。这意味着如果你有一个100K的物体,它将位于LOH上。清理对象后,您将获得100K,GC可能会决定在该洞中添加其他东西。由于它没有压实,因此无法保证空间完全填满。这会在空间中留下未完全填满的空洞并导致内存碎片化。解决此问题的唯一方法是检查转储文件,查看占用最大空间的对象,并确定可以减少的类/集合。您可能会看到很多对象数组和字符串,因为它们在缓存管理器中通常相当大。
2)你处理的是实例吗?等到终结器线程进入清理实例不应该是默认情况,因为这可能导致可怕的GC性能。确保在其继承中的某处部署了所有实现IDisposable接口的类。早期调用Dispose意味着资源以确定的方式释放,而取决于终结器意味着清理可能会发生很多,甚至更晚(如果有的话)。
3)如果你得到的是OutOfMemoryExceptions,可能是由于两个原因:你的托管内存用完了(在工作进程的情况下很少设置限制,因为它将被回收)或者你的虚拟用完了内存,如果您在32位IIS应用程序中运行,则限制为2GB的虚拟内存,这更糟糕。我们还在生产中看到了这个问题,即GC分配了64MB的堆块(工作站模式为32GB),一旦接近2GB的限制并且无法分配更多的空间,它就抛出异常(参见:{{3 }})。如果是这种情况,您可能正在泄漏托管资源,其中它根植于静态的东西,或者您没有通过使用 - =运算符删除它们来清理事件处理程序。
如果您可以发布转储文件或至少发布其相关部分,则可以更轻松地查看问题所在。但是从你的简短描述来看,这些是我要看的内容。