Which version and edition of Flyway are you using?
versions 6.1.0-6.3.2, community edition
Which client are you using? (Command-line, Java API, Maven plugin, Gradle plugin)
Java API
Which database are you using (type & version)?
Postgresql 11
Which operating system are you using?
Linux
What did you do?
We are running flyway in a Wildfly application server, and noticed that our application was being killed due to running out of heap. An initial analysis showed that Flyway was the cause of a memory leak, in particular the ResourceNameCache class seems to be ballooning in size.
Our application has a periodic job which calls the .info() method on a Flyway instance. It appears that this is the underlying reason for the memory leak.
We have performed an in-depth analysis and found a probable root cause.
The commit which causes this problem is b1e827f. It appears to have introduced a logic error when introducing the ResourceNameCache.
Our understanding is that the purpose of the ResourceNameCache is to cache intermediate results of the classpath scanning in the scope of the Flyway object, and reuse those intermediate results for future classpath scans. As such, on consecutive instantiations of the ClassPathScanner, the ResourceNameCache is passed in from outside.
Unfortunately the above change broke the functionality of the locationScannerCache in the ClassPathScanner class, this because the locationScannerCache is local to the ClassPathScanner.
Consider the first and a subsequent instantiation of the ClassPathScanner:
In the first instantiation the locationScannerCache is consulted for an entry, none is found because it is empty. So a new ClassPathLocationScanner is instantiated, and stored in the locationScannerCache. Then this location scanner is put into the ResourceNameCache, and later populated.
JamesGuthrie commentedMar 26, 2020
Which version and edition of Flyway are you using?
versions 6.1.0-6.3.2, community edition
Which client are you using? (Command-line, Java API, Maven plugin, Gradle plugin)
Java API
Which database are you using (type & version)?
Postgresql 11
Which operating system are you using?
Linux
What did you do?
We are running flyway in a Wildfly application server, and noticed that our application was being killed due to running out of heap. An initial analysis showed that Flyway was the cause of a memory leak, in particular the
ResourceNameCache
class seems to be ballooning in size.Our application has a periodic job which calls the
.info()
method on a Flyway instance. It appears that this is the underlying reason for the memory leak.We have performed an in-depth analysis and found a probable root cause.
The commit which causes this problem is b1e827f. It appears to have introduced a logic error when introducing the
ResourceNameCache
.Our understanding is that the purpose of the
ResourceNameCache
is to cache intermediate results of the classpath scanning in the scope of the Flyway object, and reuse those intermediate results for future classpath scans. As such, on consecutive instantiations of theClassPathScanner
, theResourceNameCache
is passed in from outside.Unfortunately the above change broke the functionality of the
locationScannerCache
in theClassPathScanner
class, this because thelocationScannerCache
is local to theClassPathScanner
.Consider the first and a subsequent instantiation of the
ClassPathScanner
:locationScannerCache
is consulted for an entry, none is found because it is empty. So a newClassPathLocationScanner
is instantiated, and stored in thelocationScannerCache
. Then this location scanner is put into theResourceNameCache
, and later populated.ResourceNameCache
as previously is passed into theClassPathScanner
, but it creates a new, empty,locationScannerCache
(see https://github.com/flyway/flyway/blob/master/flyway-core/src/main/java/org/flywaydb/core/internal/scanner/classpath/ClassPathScanner.java#L63). As such, when thelocationScannerCache
is consulted for a previously cachedClassPathLocationScanner
(see https://github.com/flyway/flyway/blob/master/flyway-core/src/main/java/org/flywaydb/core/internal/scanner/classpath/ClassPathScanner.java#L284), it does not return one. So once again a newClassPathLocationScanner
is instantiated and loaded into the same, shared,ResourceNameCache
, and later populated.The result is that the
ResourceNameCache
fills up with numerousClassPathLocationScanner
instances, until the JVM runs out of heap.A possible solution would be to hoist the
locationScannerCache
up to the same scope as theResourceNameCache
.The text was updated successfully, but these errors were encountered: