javac OOM / GC death spiral while indexing plugin JARs via JIFS
Summary
On a full-plugins boot, javac can get stuck before compilation starts,
scanning the classpath archives: it loops allocate → <oom/> → GC (mark/sweep/cleanup) → retry forever. gc-thread is the RUNNING thread,
the serial shell never gets a prompt back, and the VM must be power-cycled.
Seen on two separate fresh boots with the identical stack signature.
Evidence (KDB q/t)
Allocation stack of the stuck thread:
com.sun.tools.javac.file.ZipFileIndex$ZipDirectory::findCENRecord
ZipFileIndex::<init>, checkIndex, getZipFileIndex
JavacFileManager::openArchive, listContainer, list
ClassReader::fillIn, complete
- reached via
JIFSFpluginJar::read ← FileInputStream.readFully ←
ByteBuffer.put ← allocPrimitiveArray ← allocHeap, i.e. a big
readFully of a plugin JAR through the JIFS layer that never fits.
Ready queue at the time: only gc-thread (+ idle). KDB log shows
<oom/> followed by continuous <mark/><sweep/><cleanup/>.
Steps to reproduce
- Boot the
cd-x86-lite ISO, all-plugins GRUB entry (entry 1, has javac).
mkdir /jnode/tmp/ox, write a trivial file, e.g. 174-byte AccLoop1.java
(plain main + loop + println; content verified byte-exact, compiles fine
on other boots).
- Run
javac /jnode/tmp/ox/AccLoop1.java.
- Intermittently: no output, ever. KDB
q shows the stack above with
gc-thread RUNNING; <oom/> markers accumulate in the UART1/KDB log.
Suspected area
ZipFileIndex per-archive caching/retention across compilations
(core/src/openjdk javac sources) — a leak would explain why early
compiles succeed and later ones OOM.
JIFSFpluginJar.read buffering a whole archive via readFully
(org.jnode.fs.jifs) — chunked reads would lower the spike.
- Heap sizing for the full-plugin configuration (1GB VM); bumping RAM may
paper over it but the unbounded scan remains.
Impact
javac on the box is unreliable under automation; one OOM wedges the
whole guest (GC starves everything, including the serial shell).
javac OOM / GC death spiral while indexing plugin JARs via JIFS
Summary
On a full-plugins boot,
javaccan get stuck before compilation starts,scanning the classpath archives: it loops
allocate → <oom/> → GC (mark/sweep/cleanup) → retryforever.gc-threadis the RUNNING thread,the serial shell never gets a prompt back, and the VM must be power-cycled.
Seen on two separate fresh boots with the identical stack signature.
Evidence (KDB
q/t)Allocation stack of the stuck thread:
com.sun.tools.javac.file.ZipFileIndex$ZipDirectory::findCENRecordZipFileIndex::<init>,checkIndex,getZipFileIndexJavacFileManager::openArchive,listContainer,listClassReader::fillIn,completeJIFSFpluginJar::read←FileInputStream.readFully←ByteBuffer.put←allocPrimitiveArray←allocHeap, i.e. a bigreadFullyof a plugin JAR through the JIFS layer that never fits.Ready queue at the time: only
gc-thread(+ idle). KDB log shows<oom/>followed by continuous<mark/><sweep/><cleanup/>.Steps to reproduce
cd-x86-liteISO, all-plugins GRUB entry (entry 1, has javac).mkdir /jnode/tmp/ox, write a trivial file, e.g. 174-byteAccLoop1.java(plain main + loop + println; content verified byte-exact, compiles fine
on other boots).
javac /jnode/tmp/ox/AccLoop1.java.qshows the stack above withgc-threadRUNNING;<oom/>markers accumulate in the UART1/KDB log.Suspected area
ZipFileIndexper-archive caching/retention across compilations(
core/src/openjdkjavac sources) — a leak would explain why earlycompiles succeed and later ones OOM.
JIFSFpluginJar.readbuffering a whole archive viareadFully(
org.jnode.fs.jifs) — chunked reads would lower the spike.paper over it but the unbounded scan remains.
Impact
javacon the box is unreliable under automation; one OOM wedges thewhole guest (GC starves everything, including the serial shell).