我们在一个高负载(6M请求/天)的spring boot应用程序中出现了内存泄漏,它为很少的restendpoint提供服务。old_gen随时间增长缓慢,提交的内存达到容器限制,导致容器摊牌。在采取了几个堆转储后,我能够找出以下几点:
>
org.apache.catalina.webresources.cachedResource使用了大量内存,实例数约为12000,导致包括java.io.file在内的其他对象的数量类似。我尝试禁用tomcat缓存,虽然这些类从堆转储中消失了,但吞吐量不可避免地下降。有什么关于最佳实践的建议吗?
spring执行器也消耗大量内存
null
Class Name | Objects | Shallow Heap | Retained Heap
--------------------------------------------------------------------------------------------------------------------------------
org.springframework.boot.actuate.audit.InMemoryAuditEventRepository | 1 | 24 | >= 5,670,928
org.springframework.boot.actuate.audit.AuditEvent[] | 1 | 4,016 | >= 5,670,880
org.springframework.boot.actuate.audit.AuditEvent | 1,000 | 32,000 | >= 5,666,416
org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails| 1,000 | 40,000 | >= 5,319,552
--------------------------------------------------------------------------------------------------------------------------------
null
似乎达到这个程度后就稳定了。但在这种情况下,每个请求中的对象都被替换到数组中。代码(InMemoryAuditEventrePository.java)如下所示,不确定--可能这导致了一些泄漏。
this.events[this.tail] = event;
对此有什么建议吗?禁用spring执行器?
GC路径显示:
null
<pre>
Class Name | Ref. Objects | Shallow Heap | Ref. Shallow Heap | Retained Heap
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller @ 0xcadf60f8 NioBlockingSelector.BlockPoller-1 Thread| 16,884 | 136 | 1,080,576 | 920
'- contextClassLoader org.springframework.boot.loader.LaunchedURLClassLoader @ 0xc8018578 | 16,884 | 80 | 1,080,576 | 4,333,096
'- classes java.util.Vector @ 0xc82b5c90 | 16,884 | 32 | 1,080,576 | 2,706,712
'- elementData java.lang.Object[20480] @ 0xca1a5dd0 | 16,884 | 81,936 | 1,080,576 | 2,706,680
'- [7996] class com.mysql.jdbc.NonRegisteringDriver @ 0xc9b94bd8 | 16,884 | 112 | 1,080,576 | 7,272
'- connectionPhantomRefs java.util.concurrent.ConcurrentHashMap @ 0xc9b94ed8 | 16,884 | 64 | 1,080,576 | 6,528
'- table java.util.concurrent.ConcurrentHashMap$Node[256] @ 0xcc905b78 | 16,884 | 1,040 | 1,080,576 | 6,464
|- [15] java.util.concurrent.ConcurrentHashMap$Node @ 0xcc963078 | 504 | 32 | 32,256 | 128
| '- val, key com.mysql.jdbc.NonRegisteringDriver$ConnectionPhantomReference @ 0xcbfa3840 | 504 | 32 | 32,256 | 48,504
| |- discovered com.mysql.jdbc.NonRegisteringDriver$ConnectionPhantomReference @ 0xcbb4ec50| 378 | 32 | 24,192 | 48,504
| |- referent com.mysql.jdbc.JDBC4Connection @ 0xcc080018 | 126 | 1,232 | 8,064 | 32,024
| '- Total: 2 entries | | | |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
null
有线索吗?
null
<pre>
Class Name | Objects | Shallow Heap
---------------------------------------------------------------------------
char[] | 21,936 | 1,988,712
int[] | 13,191 | 1,913,760
java.lang.Object[] | 12,230 | 652,176
java.lang.String | 21,936 | 526,464
java.lang.reflect.Method | 2,994 | 263,472
java.lang.ref.SoftReference | 4,051 | 162,040
java.util.LinkedHashMap$Entry | 3,873 | 154,920
java.util.HashMap$Node[] | 2,470 | 142,784
java.util.LinkedHashMap | 2,314 | 129,584
java.lang.reflect.Constructor | 1,133 | 90,640
sun.reflect.generics.tree.SimpleClassTypeSignature| 2,776 | 66,624
java.util.ArrayList | 2,735 | 65,640
---------------------------------------------------------------------------
null
有谁能建议一下如何看到这些对象的价值(使用MAT),如何追踪?
还有其他建议吗?
在分析了堆转储之后,是否真的存在任何内存泄漏或者这是JVM的通常行为并不十分明显。我们在oracle jre 8中使用docker映像,它上次更新是在2年前。我们更改为openjdk,现在内存行为似乎更加稳定。
我有一个运行在Tomcat7上的Java web应用程序出现内存泄漏。在负载下(使用JConsole确定),应用程序的平均内存使用量随时间线性增加。在内存使用达到稳定期后,性能会显著下降。响应时间从大约100ms到[300ms,2500ms],所以这实际上导致了真正的问题。 使用VisualVM,我看到至少一半的内存被字符数组(即char[])使用,而且大多数字符串(每个实例的数量大致相同,为30
我在spring引导应用程序中面临内存泄漏,在使用Eclipse MAT进行堆转储分析之后,它指出了spring boot执行器中潜在的内存:精确地说是使用InMemoryAuditEventRepository(审计事件)。 禁用此内存审核事件的最佳方法是什么: 删除spring-boot-acturtor依赖项 management.endpoints.enabled-by-default=t
我看到了这个Python问题:应用引擎延迟:跟踪内存泄漏 ...同样,我也遇到了这个可怕的错误: 在为总共384个请求提供服务后,超过了128 MB的软专用内存限制 ... 处理此请求后,发现处理此请求的进程占用了太多内存,因此被终止。这可能会导致应用程序的下一个请求使用新进程。如果经常看到此消息,则应用程序中可能存在内存泄漏。 根据另一个问题,可能是“实例类”太小,无法运行这个应用程序,但是在增
问题内容: 我看到了这个Python问题:推迟了AppEngine:跟踪内存泄漏 …同样,我遇到了这个可怕的错误: 总共为384个请求提供服务后,超出了128 MB的软私有内存限制 … 处理此请求后,发现处理此请求的进程使用了过多的内存并被终止。这很可能导致新流程用于您的应用程序的下一个请求。如果您经常看到此消息,则可能是应用程序内存泄漏。 根据另一个问题,可能是“实例类”太小而无法运行此应用
我使用石英版和Spring Boot版。它表现正常,一切正常。但是当我试图关闭这个应用程序时,问题出现了。日志显示有内存泄漏... 我的石英配置; 我有两个班,执行如下工作; 另一个班也同样做着不同的事情。 调度器工厂Bean如下; 我得到了像下面这样的tomcat日志; 查阅了quartz文档,并在properties中添加了以下内容:; 第一条线程消息消失了,但关于worker-2的第二条消息
我有以下代码试图在一个大表上循环(~100k行;~30GB) 但是,我不断遇到以下错误: 处理此请求时,发现处理此请求的进程占用了太多内存,因此终止。这可能会导致应用程序的下一个请求使用新进程。如果经常看到此消息,则应用程序中可能存在内存泄漏。 ...有时候...... 在处理总共9个请求后,超过了128 MB的软私有内存限制,达到154 MB 我改变了我的代码,所以我总是在任何给定的时间只提取1