Suppose that I am in a 64-bit machine compiling a C program with gcc
. I'm assuming that sizeof(int)
is 8 bytes, and sizeof(char)
is 1 byte.
Because of memory alignment, the following struct:
struct example{
int a;
char c;
}
does not actually have a size of 9 bytes, but 16 (twice sizeof(int)
), so that both its beginning and ending addresses can be at multiples of the word size (assumed 8 bytes here).
I was wondering how large the following class would be in Java 8:
class Node {
int val;
Node left, right;
boolean flag;
}
I'm basically not certain whether we would align at multiples of 8 or 4 bytes.
What is alignment? Alignment refers to the arrangement of data in memory, and specifically deals with the issue of accessing data as proper units of information from main memory. First we must conceptualize main memory as a contiguous block of consecutive memory locations. Each location contains a fixed number of bits.
An object that is "8 bytes aligned" is stored at a memory address that is a multiple of 8. Many CPUs will only load some data types from aligned locations; on other CPUs such access is just faster. There's also several other possible reasons for using memory alignment - without seeing the code it's hard to say why.
A memory layout can be used to describe the contents of a memory segment in a language neutral fashion.
Yes both alignment and arrangement of your data can make a big difference in performance, not just a few percent but few to many hundreds of a percent. Take this loop, two instructions matter if you run enough loops. A performance test you can very easily do yourself.
You can use jol to know the exact layout of objects. This is the output of the program for your Node class (on Oracle JDK 1.8.0_121 64 bit):
# Running 64-bit HotSpot VM.
# Using compressed oop with 3-bit shift.
# Using compressed klass with 3-bit shift.
# Objects are 8 bytes aligned.
# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
org.example.Node object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 70 22 01 f8 (01110000 00100010 00000001 11111000) (-134143376)
12 4 int Node.val 0
16 1 boolean Node.flag false
17 3 (alignment/padding gap) N/A
20 4 Node Node.left null
24 4 Node Node.right null
28 4 (loss due to the next object alignment)
Instance size: 32 bytes
Space losses: 3 bytes internal + 4 bytes external = 7 bytes total
So, the alignment is 8 bytes.
Note, this is platform-specific. You shouldn't rely much on this information.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With