The Memory Estimator
Came across this blog post by Daniel Lemire. It’s not his most interesting or informative post, but made me remember a little utility I wrote many years ago. MemoryEstimator is a tool to estimate the memory footprint of any Java type. (It’s part of ojAlgo.) Just had to verify if its estimates are aligned with the numbers presented in that blog post. In that post there is a table of estimated memory usage for byte arrays of different sizes. These are the numbers:
| size of the array | estimated memory usage |
|---|---|
| 0 | 16 bytes |
| 1 | 24 bytes |
| 2 | 24 bytes |
| 3 | 24 bytes |
| 4 | 24 bytes |
| 5 | 24 bytes |
| 6 | 24 bytes |
| 7 | 24 bytes |
| 8 | 24 bytes |
| 9 | 32 bytes |
Now, let’s see if MemoryEstimator produces the same estimates.
Example/Test Code
TheMemoryEstimator.javaimport java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.util.OptionalDouble;
import org.ojalgo.OjAlgoUtils;
import org.ojalgo.machine.JavaType;
import org.ojalgo.machine.MemoryEstimator;
import org.ojalgo.netio.BasicLogger;
/**
* A tiny example demonstrating the use of the MemoryEstimator utility.
*
* @see https://www.ojalgo.org/2022/12/the-memory-estimator/
*/
public class TheMemoryEstimator {
public static void main(final String[] args) {
BasicLogger.debug();
BasicLogger.debug(TheMemoryEstimator.class);
BasicLogger.debug(OjAlgoUtils.getTitle());
BasicLogger.debug(OjAlgoUtils.getDate());
BasicLogger.debug();
/*
* To estimate the memory footprint of an array of any Java type, you just specify which type and the
* length of the array, and then call 'estimateArray'.
*/
BasicLogger.debug();
BasicLogger.debug("Size of byte[] of different lengths");
BasicLogger.debug("===================================");
for (int i = 0; i < 10; i++) {
long estimate = MemoryEstimator.estimateArray(byte.class, i);
BasicLogger.debug("byte[{}] == {} bytes", i, estimate);
}
/*
* There is also an enum named JavaType that enumerates Java's basic types.
*/
BasicLogger.debug();
BasicLogger.debug("Memory footprint of Java's basic types");
BasicLogger.debug("======================================");
for (JavaType type : JavaType.values()) {
BasicLogger.debug("{} {} bytes", type.getJavaClass().getSimpleName(), type.memory());
BasicLogger.debug(1, "{} bytes when wrapped/boxed in a class", type.estimateSizeOfWrapperClass());
}
/*
* It's also possible to estimate the size of any Java object.
*/
BasicLogger.debug();
BasicLogger.debug("Memory footprint of some specific types");
BasicLogger.debug("=======================================");
BasicLogger.debug("BigDecimal == {} bytes", MemoryEstimator.estimateObject(BigDecimal.class));
BasicLogger.debug("LocalDate == {} bytes", MemoryEstimator.estimateObject(LocalDate.class));
BasicLogger.debug("Instant == {} bytes", MemoryEstimator.estimateObject(Instant.class));
BasicLogger.debug("OptionalDouble == {} bytes", MemoryEstimator.estimateObject(OptionalDouble.class));
/*
* Estimating the size of complex data types containing arrays, collections and multiple references to
* other objects is meaningless (the way MemoryEstimator works). Even with the few examples above
* there's a problem. BigDecimal contains a reference to a BigInteger, but the estimate only includes
* the size of the reference to that instance – not the size of the BigInteger instance itself.
*/
}
}
Console Output
class TheMemoryEstimator
ojAlgo
2022-12-01
Size of byte[] of different lengths
===================================
byte[0] == 16 bytes
byte[1] == 24 bytes
byte[2] == 24 bytes
byte[3] == 24 bytes
byte[4] == 24 bytes
byte[5] == 24 bytes
byte[6] == 24 bytes
byte[7] == 24 bytes
byte[8] == 24 bytes
byte[9] == 32 bytes
Memory footprint of Java's basic types
======================================
boolean 1 bytes
16 bytes when wrapped/boxed in a class
byte 1 bytes
16 bytes when wrapped/boxed in a class
char 2 bytes
16 bytes when wrapped/boxed in a class
double 8 bytes
24 bytes when wrapped/boxed in a class
float 4 bytes
16 bytes when wrapped/boxed in a class
int 4 bytes
16 bytes when wrapped/boxed in a class
long 8 bytes
24 bytes when wrapped/boxed in a class
Object 4 bytes
16 bytes when wrapped/boxed in a class
short 2 bytes
16 bytes when wrapped/boxed in a class
Memory footprint of some specific types
=======================================
BigDecimal == 40 bytes
LocalDate == 24 bytes
Instant == 24 bytes
OptionalDouble == 24 bytes
- ← Previous
Optimisation-as-a-Service - Next →
Who Uses ojAlgo?