简体   繁体   English

Spring Boot(2.0.3.RELEASE)应用程序中的内存泄漏

[英]Memory Leak in Spring boot(2.0.3.RELEASE) application

We are having a memory leak in a high load(6m req/day) Spring boot application, serving few rest endpoints. 我们在高负载(每天6m req / day)的Spring Boot应用程序中发生内存泄漏,只为少数几个端点提供服务。 old_gen grow slowly over time and committed memory reaches the container limit, causing container showdown. old_gen随时间增长缓慢,并且已提交的内存达到容器限制,从而导致容器摊牌。 After taking several heapdump, I was able to find out the following: 经过几次堆转储后,我能够找到以下内容:

  1. A good amount of memory is used by org.apache.catalina.webresources.CachedResource, with an instance count of around 12000, causing similar amount of other objects including java.io.File. org.apache.catalina.webresources.CachedResource使用了大量的内存,实例计数大约为12000,导致其他数量的对象(包括java.io.File)也差不多。 I tried disabling tomcat caching, while these classes are gone from heapdump but the throughput decreases inevitably. 我尝试禁用tomcat缓存,尽管这些类已从heapdump中删除,但吞吐量不可避免地降低了。 Any suggestions on the best practice? 对最佳做法有何建议?

  2. Spring actuator also consumes good amount of memory 弹簧执行器还占用大量内存

 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 -------------------------------------------------------------------------------------------------------------------------------- 

It seems to be stable after reaching this level. 达到此水平后似乎稳定。 But in that case on every request, the objects are being replaced in the array. 但是在那种情况下,对于每个请求,对象都会在数组中被替换。 The code(InMemoryAuditEventRepository.java) looks like below, not sure - maybe this causes some leak. 代码(InMemoryAuditEventRepository.java)如下所示,不确定-可能会导致一些泄漏。

this.events[this.tail] = event;

Any suggestions on this? 有什么建议吗? disable spring actuator? 禁用弹簧执行器?

  1. 17670 instances of this class: org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource$DefaultCacheKey. 此类的17670个实例:org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource $ DefaultCacheKey。 Also seems stable like previous class. 也像上课一样稳定。 Seems like related to caching. 似乎与缓存有关。
  2. 20000 instances of com.mysql.jdbc.ConnectionPropertiesImpl$BooleanConnectionProperty! com.mysql.jdbc.ConnectionPropertiesImpl $ BooleanConnectionProperty的20000个实例!

Path to GC shows: GC的路径显示:

 <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 | | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

Any clue? 有什么线索吗?

  1. Heapdump also shows some unreachable objects. 堆转储还显示了一些无法访问的对象。 Count 128,249 consuming 7MB, major of which are: 计数128,249消耗7MB,主要是:

 <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 --------------------------------------------------------------------------- 

Can anyone suggests how to see the value of these objects (using MAT), how to track down? 谁能提出建议(使用MAT)如何查看这些对象的值,如何进行追踪?

Any other suggestions? 还有其他建议吗?

After analyzing the heapdumps, its not quite obvious if there is actually any memory leak or it is JVM's usual behavior. 在分析了堆转储之后,如果实际上有任何内存泄漏或者这是JVM的通常行为,则不是很明显。 We were using docker image with oracle jre 8, which was last updated 2 years ago. 我们将docker image与oracle jre 8一起使用,该镜像最近更新于2年前。 We changed to openjdk and now the memory behavior seems much more stable. 我们更改为openjdk,现在内存行为似乎更加稳定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM