Skip to content

@Async with cglib based proxy causes memory leak in permgen [SPR-11276] #15900

Closed
@spring-projects-issues

Description

@spring-projects-issues

Lukasz Rozek opened SPR-11276 and commented

running mvn clean package && mvn exec:exec -PpermLeak
against repro project that can be found here
https://github.com/lrozek/spring-leak
or https://github.com/lrozek/spring-leak/archive/master.zip
or git clone https://github.com/lrozek/spring-leak.git

causes java.lang.OutOfMemoryError: PermGen space in 1693 iteration
The stacktrace isn't logged, I guess the reason for that is insufficient memory to load classes that are needed to log it

--iteration 1693

2014-01-02 13:10:36,718 [main] INFO  pl.lrozek.spring.leak.main.LeakMain - 1693 calleeThreadName is SimpleAsyncTaskExecutor-1, callerThreadName is main, areThreadsTheSame: false
[Loaded sun.reflect.GeneratedConstructorAccessor18 from __JVM_DefineClass__]
[Loaded sun.reflect.GeneratedMethodAccessor32 from __JVM_DefineClass__]
[Loaded sun.reflect.GeneratedMethodAccessor33 from __JVM_DefineClass__]
[GC [PSYoungGen: 10086K->352K(340992K)] 164828K->155093K(1037824K), 0.0015840 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
[Full GC[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor1694]
[Unloading class sun.reflect.GeneratedMethodAccessor31]
 [PSYoungGen: 352K->0K(340992K)] [ParOldGen: 154741K->154947K(697856K)] 155093K->154947K(1038848K) [PSPermGen: 65535K->65531K(65536K)], 0.5844170 secs] [Times: user=3.66 sys=0.03, real=0.58 secs] 
[GC [PSYoungGen: 0K->0K(340992K)] 154947K->154947K(1038848K), 0.0015100 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
[Full GC [PSYoungGen: 0K->0K(340992K)] [ParOldGen: 154947K->154947K(698368K)] 154947K->154947K(1039360K) [PSPermGen: 65535K->65535K(65536K)], 0.2045020 secs] [Times: user=1.15 sys=0.00, real=0.21 secs] 
[GC [PSYoungGen: 0K->0K(340992K)] 154947K->154947K(1039360K), 0.0024050 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC[Unloading class sun.reflect.GeneratedMethodAccessor32]
[Unloading class sun.reflect.GeneratedMethodAccessor33]
[Unloading class sun.reflect.GeneratedConstructorAccessor18]
 [PSYoungGen: 0K->0K(340992K)] [ParOldGen: 154947K->154850K(698368K)] 154947K->154850K(1039360K) [PSPermGen: 65535K->65529K(65536K)], 0.2422960 secs] [Times: user=1.40 sys=0.00, real=0.24 secs] 
[Loaded pl.lrozek.spring.leak.service.AsyncService$$EnhancerByCGLIB$$3e49d941_1695 from file:/home/lucas/.m2/repository/org/springframework/spring-core/4.0.0.RELEASE/spring-core-4.0.0.RELEASE.jar]
[Loaded sun.reflect.GeneratedSerializationConstructorAccessor1695 from __JVM_DefineClass__]
[GC [PSYoungGen: 1720K->64K(339968K)] 156570K->154914K(1038336K), 0.0042700 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
[Full GC [PSYoungGen: 64K->0K(339968K)] [ParOldGen: 154850K->154835K(698880K)] 154914K->154835K(1038848K) [PSPermGen: 65535K->65535K(65536K)], 0.1905130 secs] [Times: user=1.06 sys=0.00, real=0.19 secs] 
[GC [PSYoungGen: 0K->0K(340480K)] 154835K->154835K(1039360K), 0.0012260 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
[Full GC [PSYoungGen: 0K->0K(340480K)] [ParOldGen: 154835K->154829K(698880K)] 154835K->154829K(1039360K) [PSPermGen: 65535K->65535K(65536K)], 0.5169370 secs] [Times: user=3.18 sys=0.01, real=0.52 secs]

--OOME thrown

java.lang.OutOfMemoryError: PermGen space
Dumping heap to java_pid32668.hprof ...
Heap dump file created [263618451 bytes in 2.532 secs]

Following logs are before OOME is thrown

--iteration 1688
2014-01-02 13:10:35,049 [main] INFO  pl.lrozek.spring.leak.main.LeakMain - 1688 calleeThreadName is SimpleAsyncTaskExecutor-1, callerThreadName is main, areThreadsTheSame: false
[Loaded pl.lrozek.spring.leak.service.AsyncService$$EnhancerByCGLIB$$3e49d941_1690 from file:/home/lucas/.m2/repository/org/springframework/spring-core/4.0.0.RELEASE/spring-core-4.0.0.RELEASE.jar]
[Loaded sun.reflect.GeneratedSerializationConstructorAccessor1690 from __JVM_DefineClass__]
[Loaded pl.lrozek.spring.leak.service.AsyncService$$EnhancerByCGLIB$$3e49d941_1690$$FastClassByCGLIB$$c5b82ced from file:/home/lucas/.m2/repository/org/springframework/spring-core/4.0.0.RELEASE/spring-core-4.0.0.RELEASE.jar]

--iteration 1689
2014-01-02 13:10:35,060 [main] INFO  pl.lrozek.spring.leak.main.LeakMain - 1689 calleeThreadName is SimpleAsyncTaskExecutor-1, callerThreadName is main, areThreadsTheSame: false
[Loaded pl.lrozek.spring.leak.service.AsyncService$$EnhancerByCGLIB$$3e49d941_1691 from file:/home/lucas/.m2/repository/org/springframework/spring-core/4.0.0.RELEASE/spring-core-4.0.0.RELEASE.jar]
[Loaded sun.reflect.GeneratedSerializationConstructorAccessor1691 from __JVM_DefineClass__]
[Loaded pl.lrozek.spring.leak.service.AsyncService$$EnhancerByCGLIB$$3e49d941_1691$$FastClassByCGLIB$$c5b82cee from file:/home/lucas/.m2/repository/org/springframework/spring-core/4.0.0.RELEASE/spring-core-4.0.0.RELEASE.jar]


--iteration 1690
2014-01-02 13:10:35,071 [main] INFO  pl.lrozek.spring.leak.main.LeakMain - 1690 calleeThreadName is SimpleAsyncTaskExecutor-1, callerThreadName is main, areThreadsTheSame: false
[Loaded sun.reflect.GeneratedSerializationConstructorAccessor1692pl.lrozek.spring.leak.service.AsyncService$$EnhancerByCGLIB$$3e49d941_1692 from file:/home/lucas/.m2/repository/org/springframework/spring-core/4.0.0.RELEASE/spring-core-4.0.0.RELEASE.jar]
[Loaded sun.reflect.GeneratedSerializationConstructorAccessor1692 from __JVM_DefineClass__]
[Loaded pl.lrozek.spring.leak.service.AsyncService$$EnhancerByCGLIB$$3e49d941_1692$$FastClassByCGLIB$$c5b82cef from file:/home/lucas/.m2/repository/org/springframework/spring-core/4.0.0.RELEASE/spring-core-4.0.0.RELEASE.jar]


--iteration 1691
2014-01-02 13:10:35,082 [main] INFO  pl.lrozek.spring.leak.main.LeakMain - 1691 calleeThreadName is SimpleAsyncTaskExecutor-1, callerThreadName is main, areThreadsTheSame: false
[Loaded pl.lrozek.spring.leak.service.AsyncService$$EnhancerByCGLIB$$3e49d941_1693 from file:/home/lucas/.m2/repository/org/springframework/spring-core/4.0.0.RELEASE/spring-core-4.0.0.RELEASE.jar]
[GC [PSYoungGen: 96317K->1376K(335872K)] 259595K->164653K(704000K), 0.0020840 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
[Full GC

[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor1684]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor1692]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor1687]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor1691]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor1688]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor1685]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor1690]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor1686]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor1689]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor1683]

 [PSYoungGen: 1376K->0K(335872K)] [ParOldGen: 163277K->164203K(484352K)] 164653K->164203K(820224K) [PSPermGen: 65534K->65501K(65536K)], 0.7856260 secs] [Times: user=4.81 sys=0.01, real=0.78 secs] 
[Loaded sun.reflect.GeneratedSerializationConstructorAccessor1693 from __JVM_DefineClass__]
[Loaded pl.lrozek.spring.leak.service.AsyncService$$EnhancerByCGLIB$$3e49d941_1693$$FastClassByCGLIB$$c5b82cf0 from file:/home/lucas/.m2/repository/org/springframework/spring-core/4.0.0.RELEASE/spring-core-4.0.0.RELEASE.jar]


2014-01-02 13:10:35,882 [main] INFO  pl.lrozek.spring.leak.main.LeakMain - 1692 calleeThreadName is SimpleAsyncTaskExecutor-1, callerThreadName is main, areThreadsTheSame: false

As you can notice, every iteration (when application context is created from scratch) loads following classes:

  • pl.lrozek.spring.leak.service.AsyncService$$EnhancerByCGLIB$$3e49d941_1692
  • pl.lrozek.spring.leak.service.AsyncService$$EnhancerByCGLIB$$3e49d941_1692$$FastClassByCGLIB$$c5b82cef
  • sun.reflect.GeneratedSerializationConstructorAccessor1692

where the two first classes aren't unloaded and cause memory leak in perm gen

This can be seen in iteration 1691 when Full GC occurs and following classes are unloaded:

  • Unloading class sun.reflect.GeneratedSerializationConstructorAccessor1684
  • Unloading class sun.reflect.GeneratedSerializationConstructorAccessor1692
  • Unloading class sun.reflect.GeneratedSerializationConstructorAccessor1687
  • Unloading class sun.reflect.GeneratedSerializationConstructorAccessor1691
    ...

In attached screenshot you can notice how memory leaks in perm while application contexts are created / closed
!perm leak.png!


Affects: 3.2.6, 4.0 GA

Reference URL: https://github.com/lrozek/spring-leak

Attachments:

Issue Links:

Referenced from: commits be2d915, 0de307b

Backported to: 3.2.7

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)status: backportedAn issue that has been backported to maintenance branchestype: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions