I was considering using the Timer class for a large number of TimerTasks (say one or two million). The heap implementation for Timer is array based, and since there is no way to reserve space for the array, the question arises, how does Java handle allocation of large contiguous memory blocks (for an array in this case) when memory is fragmented?
Will an OutOfMemoryError always be thrown if there is no fragment available big enough? Or can I expect the JVM to have some kind of memory de-fragmentation strategy when the total amount of free memory is enough?
Edit: It appears there is no JVM implementation independent answer to my question. In my case the JVM implementation is OpenJDK version 14.0-b16 (according to the java.vm.name and java.vm.version system properties).
First of all, this is not defined by the Java Language Specification, so any concrete answers you’ll get will be implementation dependent. I don’t even believe it is defined in the Virtual Machine Specification.
In fact, I suggest you narrow down your question to a specific JVM implementation.
Since Java hides the actual memory addresses it can perform memory compaction at will. So yes, you can expect it to have memory defragmentation strategies. (Keep in mind though that your operating system probably provides the JVM with virtual memory, so you have yet another layer between your application and the physical addresses.)