Questo SO answer chiarisce alcune cose sul flag JVM -Xmx
. Cercando di sperimentare ho fatto la seguente:è -Xmx un limite rigido?
import java.util.List;
import java.util.ArrayList;
public class FooMain {
private static String memoryMsg() {
return String.format("%s. %s. %s"
, String.format("total memory is: [%d]",Runtime.getRuntime().totalMemory())
, String.format("free memory is: [%d]",Runtime.getRuntime().freeMemory())
, String.format("max memory is: [%d]",Runtime.getRuntime().maxMemory()));
}
public static void main(String args[]) {
String msg = null;
try {
System.out.println(memoryMsg());
List<Object> xs = new ArrayList<>();
int i = 0 ;
while (true) {
xs.add(new byte[1000]);
msg = String.format("%d 1k arrays added.\n%s.\n"
, ++i
, memoryMsg());
}
} finally {
System.out.printf(msg);
}
}
}
compilarlo con javac FooMain.java
. Quando eseguo con una dimensione massima mucchio di 5 milioni di byte ottengo:
java -Xmx5000000 FooMain
total memory is: [5242880]. free memory is: [4901096]. max memory is: [5767168]
4878 1k arrays added.
total memory is: [5767168]. free memory is: [543288]. max memory is: [5767168].
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.lang.String.toCharArray(String.java:2748)
at java.util.Formatter$FormatSpecifier.print(Formatter.java:3048)
at java.util.Formatter$FormatSpecifier.printInteger(Formatter.java:2744)
at java.util.Formatter$FormatSpecifier.print(Formatter.java:2702)
at java.util.Formatter.format(Formatter.java:2488)
at java.util.Formatter.format(Formatter.java:2423)
at java.lang.String.format(String.java:2792)
at FooMain.memoryMsg(FooMain.java:7)
at FooMain.main(FooMain.java:21)
Anche se i numeri sono abbastanza vicini, non sembrano molto preciso (con l'eccezione del total memory
alla fine raggiungere esattamente il max memory
). In particolare 5368 matrici di 1000 byte ciascuna dovrebbero richiedere più di 5000000 o anche 5242880 byte. Come dovrebbero essere compresi questi numeri?
Questa è la Java che sto utilizzando:
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) Server VM (build 24.80-b11, mixed mode)
Forse Garbage Collection è stato avviato nel frattempo ... –
@RobertNiestroj non è possibile poiché tutti i riferimenti sono mantenuti –
@RobertNiestroj perché dovrebbe essere qualcosa GCed? Sto aggiungendo gli array in un 'List'. Nessun riferimento va oltre lo scopo. –