Runtime.freeMemory
gibt nur eine grobe Schätzung zurück. Es eignet sich nicht zum Messen von Speicher, der von einem bestimmten Objekt belegt ist.
Sie können JMH mit eingebautem -prof gc
Profiler verwenden, um eine viel genauere Schätzung zu erhalten. Hier ist ein Beispiel-Benchmark, um den von einer HashMap belegten Speicherplatz zu messen (ohne den Speicher, der von Schlüsseln und Werten selbst verwendet wird).
package bench;
import org.openjdk.jmh.annotations.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@State(Scope.Benchmark)
public class MapSizeBench {
@Param({"10", "100", "1000", "10000", "100000"})
int size;
Map<String, Double> map;
@Setup
public void setup() {
map = IntStream.range(0, size).boxed().collect(Collectors.toMap(
n -> "key" + n,
n -> ThreadLocalRandom.current().nextDouble()));
}
@Benchmark
public Map<String, Double> hashMap() {
return new HashMap<>(map);
}
}
gc.alloc.rate.norm
Wert die Anzahl von Bytes zugewiesen zeigen, während das Verfahren mit @Benchmark
Annotation gekennzeichnet ausführt:
Benchmark (size) Mode Cnt Score Error Units
MapSizeBench.hashMap:·gc.alloc.rate.norm 10 avgt 5 448,000 ± 0,001 B/op
MapSizeBench.hashMap:·gc.alloc.rate.norm 100 avgt 5 4288,001 ± 0,001 B/op
MapSizeBench.hashMap:·gc.alloc.rate.norm 1000 avgt 5 40256,009 ± 0,002 B/op
MapSizeBench.hashMap:·gc.alloc.rate.norm 10000 avgt 5 385640,093 ± 0,017 B/op
MapSizeBench.hashMap:·gc.alloc.rate.norm 100000 avgt 5 4248681,606 ± 0,329 B/op
Das heißt, ein HashMap von 1000 Elementen nimmt ungefähr 40 KB auf JDK 8 x64 mit CompressedOops aktiviert.
Alternativ können Sie die volle Heapdump nehmen:
jmap -dump:format=b,file=heap.hprof <pid>
und analysieren es in Eclipse Memory Analyzer. Dieses Tool kann Ihnen den Speicher zeigen, der von einem bestimmten Objekt oder einem Objektgraphen belegt ist.
http://java-performance.info/memory-consumption-of- Java-Datentypen-2 / – Rjiuk