Java is an object-oriented language, so it creates objects in storage, generally a lot of objects.
What is more, Java provides automatic garbage collection (GC), which means that sometime after an object is no longer able to be accessed by any running Java code, the Garbage Collector will make sure it is deleted.
The IBM i server allows the amount of real (as opposed to virtual) memory to be specified by a Memory Pool.
Page faults occur whenever the actual size of your GC heap, and any other programs using memory from that pool if the pool is shared, exceed the amount of real memory specified in the pool.
Excessive page faults may occur if the memory pool for your JVM is too small.
These faults will be reported as non-database page faults on the WRKSYSSTS command display.
A memory pool also has an activity level associated with it which specifies the number of threads that can actively use processor(s) at the same time from that memory pool.
When more threads are started than allowed to concurrently execute due to the activity level control, the excess threads will be forced to wait for an available activity level slot before they can run.
The number of threads running (active threads) refers to the number of threads that are eligible to compete for a processor and that count against the activity level for a memory pool.
Active threads do not include threads that are waiting for input, for a message, for a device to be allocated, or for a file to be opened.
Active threads do not include threads that are ineligible (threads that are ready to run but the memory pool activity level is at its maximum).
Once the maximum activity level for a memory pool has been reached, additional threads needing the memory pool are placed in the ineligible state.
The threads wait in ineligible state for the number of active threads in the memory pool to fall below the maximum activity level, or for a thread to reach the end of its time slice.
As soon as a thread gives up its use of the memory pool, the other threads that are not active become eligible, and will be dispatched based on their priority.
Having Java threads in the ineligible state can cause severe performance degradation as well as excessive JVM GC heap growth.
To avoid this condition, set the activity level of the memory pool to at least as large as the maximum number of threads you expect to be concurrently active at any time for the JVM running in the memory pool.