Memory Configuration
JVM memory flags, off-heap configuration, and memory management for ND4J and DL4J
Overview
DL4J and ND4J use two distinct memory regions:
JVM heap — managed by the Java garbage collector. Holds Java objects, model configurations, and metadata.
Off-heap memory — allocated outside the JVM, managed by JavaCPP. Holds all
INDArraydata (tensor contents). This memory is shared with native C++ code and, when using CUDA, with GPU memory.
Understanding both regions and setting appropriate limits is critical to avoiding out-of-memory (OOM) errors and achieving good performance.
JVM Heap Flags
-Xms<size>
Initial JVM heap size. JVM allocates this at startup.
-Xmx<size>
Maximum JVM heap size. JVM will not exceed this limit.
Examples:
-Xms2G -Xmx8G # Start with 2 GB, allow up to 8 GB
-Xms512m -Xmx2G # Lightweight processRecommendation: Keep the JVM heap relatively small. DL4J's training data and model parameters live in off-heap memory, not on the JVM heap. A typical setting is Xmx2G to Xmx8G. Setting Xmx too high leaves less room for off-heap memory.
Off-Heap Memory Flags
-Dorg.bytedeco.javacpp.maxbytes=<size>
Maximum off-heap memory for JavaCPP (and ND4J). On GPU systems, this also controls how much GPU memory ND4J may allocate.
-Dorg.bytedeco.javacpp.maxphysicalbytes=<size>
Maximum total process memory. Should be set to maxbytes + Xmx + overhead. Optional but useful to prevent runaway allocation.
Size suffixes: K, M, G (e.g., 8G = 8 gigabytes).
Example — 1 GB JVM, 2 GB max JVM, 8 GB off-heap, 11 GB total process cap:
If maxbytes is not set, it defaults to the value of -Xmx. This means a process with -Xmx8G would allow 8 GB for JVM heap AND 8 GB for off-heap — totalling up to 16 GB of RAM usage.
Recommended Configurations
Development workstation (16 GB RAM, CPU only)
Server training (64 GB RAM, CPU only)
GPU training (24 GB VRAM, 64 GB system RAM)
Set maxbytes slightly below VRAM capacity to leave room for CUDA runtime overhead and cuDNN workspace allocations.
Inference server (low latency, 32 GB RAM, CPU)
GPU Memory Management
When using the CUDA backend (nd4j-cuda-*), off-heap memory is mapped to GPU memory. The maxbytes flag controls how much GPU RAM ND4J is permitted to allocate. The GPU and CPU off-heap pools share this limit.
ND4J also allocates a CPU-side off-heap mirror buffer for each GPU array to allow efficient CPU-GPU communication. This is why CPU RAM usage will always be higher than GPU VRAM usage in a CUDA setup.
Rule of thumb for GPU memory
Set maxbytes close to — but not exceeding — your GPU's available VRAM. Subtract approximately 1 GB to 2 GB for CUDA runtime and driver overhead:
Minimum GPU VRAM requirements
Deep learning workloads generally require:
4 GB VRAM minimum (small networks, small batches)
8 GB VRAM recommended
16 GB+ for large CNNs or transformers with moderate batch sizes
GPUs with less than 2 GB VRAM are not suitable for DL4J training.
Using HOST_ONLY memory with CUDA
In some cases you may need arrays that reside in CPU RAM even when using the CUDA backend. Use MirroringPolicy.HOST_ONLY in a workspace configuration:
This is only recommended for in-memory cache scenarios where you use INDArray.unsafeDuplication(). Host-only arrays are slow to use in computation because they must be copied to GPU for each operation.
Memory-Mapped Files
The nd4j-native (CPU) backend supports memory-mapped files, allowing you to work with INDArray data that exceeds available RAM:
The file is created as a temp file and cleaned up when the workspace is closed. Performance is lower than RAM-backed arrays but allows processing datasets that do not fit in memory.
Garbage Collection Configuration
The JVM garbage collector can cause "stop-the-world" pauses that disrupt training. Since ND4J manages array memory off-heap through workspaces, GC pauses primarily affect the JVM-side object lifecycle.
ND4J's periodic GC
ND4J calls System.gc() periodically to trigger cleanup of WeakReference objects that track off-heap allocations. By default this occurs every 5 seconds. During training with workspaces enabled, this is usually unnecessary and can introduce latency.
Reduce GC frequency:
Disable periodic GC entirely (safe when workspaces are enabled for all operations):
Place these calls before model.fit(...).
JVM GC tuning flags
For training workloads, G1GC is a reasonable default on Java 11+:
If you have a large JVM heap (>16 GB), ZGC or Shenandoah can reduce pause times further:
Diagnosing OOM Errors
Can't allocate [HOST] memory
This means the off-heap memory limit was exceeded. Solutions:
Increase
maxbytes:-Dorg.bytedeco.javacpp.maxbytes=16GEnable workspaces so memory is reused instead of newly allocated each iteration.
Reduce batch size to lower peak memory usage per iteration.
Check for memory leaks: arrays created in loops without a workspace scope will accumulate.
CUDA out of memory
This means GPU VRAM was exhausted. Solutions:
Reduce batch size.
Switch to
NO_WORKSPACEcuDNN algo mode if using cuDNN, asPREFER_FASTESTallocates large workspace buffers.Verify
maxbytesis not set higher than available VRAM.Check that no leftover arrays from previous iterations are being retained in memory.
JVM heap OOM
This is a JVM-side issue, not off-heap. Solutions:
Increase
-Xmx.Check for accumulation of Java objects (e.g., storing DataSet objects in a large list).
Use a profiler to identify which objects dominate heap usage.
Diagnosing with heap dumps
To capture a heap dump for analysis:
Open the .hprof file in VisualVM or YourKit to see object counts by type.
Monitoring Memory Usage
At runtime
GPU memory
Summary of Common Pitfalls
High -Xms + large -Xmx on a constrained system
No room for off-heap
Keep -Xms small; reduce -Xmx
No maxbytes set
Off-heap defaults to -Xmx value, may be insufficient
Set maxbytes explicitly
maxbytes > GPU VRAM
CUDA OOM
Set maxbytes to VRAM - 1–2 GB
Arrays created outside workspaces in training loop
Slow GC pressure, OOM
Enable workspaces; see Workspaces
Periodic GC enabled during workspace-based training
Latency spikes
setAutoGcWindow(10000) or disable
Related Pages
Workspace Configuration — workspace-based memory management
GPU and CPU Setup — backend selection
Performance Debugging — diagnosing slowdowns and OOM errors
Last updated
Was this helpful?