I have a Java app that include a big file into its resource (650MB).
Somewhere in my code, I'm using this resource with :
this.getClass().getResourceAsStream("...") When running the app in the dev environment (Gradle based), the app is running without any problem.
If I build a jlink image of this app (using jdk-21.0.2+13 from temurin21) the same line will throw
java.lang.OutOfMemoryError: Java heap space After studying the memory with VisualVM, it seems that the memory is stable in my dev env while it is not when running on the JLink image.
I guess that the resource is not retrieved the same way depending the image is packaged with JLink or dynamically running with Gradle. However I don't understand if this is an internal issue or how I can bypass it.
I know about "Xmx" option, but this is not the solution : running with "Xmx512M" will be fine in dev but will cause OOM in jlink image.
Here is the full stack trace of the error :
java.lang.OutOfMemoryError: Java heap space at java.base/jdk.internal.jimage.BasicImageReader.getBufferBytes(Unknown Source) at java.base/jdk.internal.jimage.BasicImageReader.getResourceBuffer(Unknown Source) at java.base/jdk.internal.jimage.ImageReader.getResourceBuffer(Unknown Source) at java.base/jdk.internal.module.SystemModuleFinders$SystemModuleReader.read(Unknown Source) at java.base/jdk.internal.module.SystemModuleFinders$SystemModuleReader.open(Unknown Source) at java.base/jdk.internal.loader.BuiltinClassLoader.findResourceAsStream(Unknown Source) at java.base/java.lang.Class.getResourceAsStream(Unknown Source) Thanks a lot !
-Xmx1Gor more? Unpacking a 650 MB file into 512 MB of memory will not fit. 2) A .jar file is basically a .zip file. When a resource file is packed inside a .jar file, it has to be decompressed in-memory/ on the go. Perhaps the resource loader does not stream that file block-by-block, but unpacks everything into memory before granting access. So a) try to adapt the resource loader, or b) try to access this packed resource file in a different way (like manually finding the .jar file, then using an in-memory ZipInputStream or sth alike).getResourceAsStream("xyz")is unpacking to memory, it is probably assigning 650MB as ByteArrayInputStreamFiles.copy(Paths.get(getResource("xyz").toURI()), ...)would work?