Description
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:
- perm leak.png (18.43 kB)
Issue Links:
- MemoryLeak in Cglib2AopProxy.ProxyCallbackFilter [SPR-8008] #12663 MemoryLeak in Cglib2AopProxy.ProxyCallbackFilter
- @Async with cglib based proxy causes memory leak in heap [SPR-11275] #15899
@Async
with cglib based proxy causes memory leak in heap
Referenced from: commits be2d915, 0de307b
Backported to: 3.2.7