Memory usage of Java objects: general guide

 
 

On this page, we take a general look at how to calculate the memory usage of a Java object, or at least anestimate of its usage. (Note that using the Classmexer agent from this site— or VM insturmentation generally— you can query the size of a Java object from within your program.)

We'll generally be talking about the memory taken up on the heap by a given object under "normal circumstances". A couple of minor complications that we'll gloss over are that:

  • in some cases, a JVM may not put an object on the heap at all: for example, a small thread-local object could in principle be held entirely on the stack or in registers and not "exist" strictly speaking as a Java heap object;
  • the overall memory impact of an object can depend on its current state: for example, whether its synchronization lock iscontended, or whether it is being garbage collected (such extra "system" data is not necessarily allocated on the Java heap, however).

On this page, we look at the memory usage of a Java object generally. On the next pages, we'll look specifically at thememory usage ofStrings and related objects.

General formula for calculating memory usage

In general, the heap memory used by a Java object in Hotspot consists of:

  • an object header, consisting of a few bytes of "housekeeping" information;
  • memory for primitive fields, according to their size (see below);
  • memory for reference fields (4 bytes each);
  • padding: potentially a few "wasted" unused bytes after the object data, to make every object start at an address that is a convenient multiple of bytes and reduce the number of bits required to represent a pointer to an object.

Sizes of primitive types

In case you're not familiar with the byte size of the different Java primitive data types, here is the complete list:

Java typeBytes required
boolean1
byte
char2
short
int4
float
long8
double

2B, CS,IPHONE,老爹

 

You may have expected a boolean to take up a single bit, or an eighth of a byte, especially if an object had 8boolean fields. In practice, Hotspot (and, I believe, VMs generally) allocate a whole byte to each boolean*.

* The reason is simply ease and efficiency of implementation: generally, we want to assign a "byte offset" to each field of a class and use a simple instruction to read/write an individual byte. It would be awkward if we had to cope with sub-byte offsets for certain fields, and it would require extra logic to read/write individual bits at a given position rather than just the whole byte each time the boolean was accessed.

Object overhead for "housekeeping" information

Instances of an object on the Java heap don't just take up memory for their actual fields. Inevitably, they also require some "housekeeping" information, such as recording an object's class, ID and status flags such as whether the object is currently reachable, currently synchronization-locked etc.

In Hotspot:
  • a normal object requires 8 bytes of "housekeeping" space;
  • arrays require 12 bytes (the same as a normal object, plus 4 bytes for the array length).

Other JVMs probably have a similar object overhead.

Object size granularity

In Hotspot, every object occupies a number of bytes that is a multiple of 8. If the number of bytes required by an object for its header and fields is not a multiple 8, then youround up to the next multiple of 8.

This means, for example, that:

  • a bare Object takes up 8 bytes;
  • an instance of a class with a single boolean field takes up 16 bytes: 8 bytes of header, 1 byte for the boolean and 7 bytes of "padding" to make the size up to a multiple of 8;
  • an instance with eight boolean fields will also take up 16 bytes: 8 for the header, 8 for the booleans; since this is already a multiple of 8, no padding is needed;
  • an object with a two long fields, three int fields and a boolean will take up:
    • 8 bytes for the header;
    • 16 bytes for the 2 longs (8 each);
    • 12 bytes for the 3 ints (4 each);
    • 1 byte for the boolean;
    • a further 3 bytes of padding, to round the total up from 37 to 40, a multiple of 8.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值