Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
spring-projects-issues opened this issue Jan 2, 2014 · 2 comments

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Jan 2, 2014

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:

  • #12663 MemoryLeak in Cglib2AopProxy.ProxyCallbackFilter
  • #15899 @Async with cglib based proxy causes memory leak in heap

Referenced from: commits be2d915, 0de307b

Backported to: 3.2.7

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jan 2, 2014

Lukasz Rozek commented

this is closely related to https://jira.springsource.org/browse/SPR-11275

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jan 4, 2014

Juergen Hoeller commented

See resolution comment in #15899.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants