java 消耗内存_Java中的对象的内存消耗是多少?

Mindprod指出,这不是一个简单的问题回答:

A JVM is free to store data any way it pleases internally, big or little endian, with any amount of padding or overhead, though primitives must behave as if they had the official sizes.

For example, the JVM or native compiler might decide to store a boolean[] in 64-bit long chunks like a BitSet. It does not have to tell you, so long as the program gives the same answers.

It might allocate some temporary Objects on the stack.

It may optimize some variables or method calls totally out of existence replacing them with constants.

It might version methods or loops, i.e. compile two versions of a method, each optimized for a certain situation, then decide up front which one to call.

Then of course the hardware and OS have multilayer caches, on chip-cache, SRAM cache, DRAM cache, ordinary RAM working set and backing store on disk. Your data may be duplicated at every cache level. All this complexity means you can only very roughly predict RAM consumption.

测量方法

对象头和对象引用

在现代的64位JDK中,对象具有12字节的标头,填充为8个字节的倍数,因此最小对象大小为16个字节。对于32位JVM,开销为8字节,填充为4个字节的倍数。 (从Dmitry Spikhalskiy’s answer,Jayen’s answer和JavaWorld)

通常,引用在32位平台上的4字节或在-Xmx32G上的64位平台上;和高于32Gb(-Xmx32G)的8个字节。 (见compressed object references.)

因此,64位JVM通常需要30-50%的更多堆空间。 (Should I use a 32- or a 64-bit JVM?,2012,JDK 1.7)

框类型,数组和字符串

与原始类型相比,Boxed包装器具有开销(从JavaWorld开始):

Integer: The 16-byte result is a little worse than I expected because an int value can fit into just 4 extra bytes. Using an Integer costs me a 300 percent memory overhead compared to when I can store the value as a primitive type

Long: 16 bytes also: Clearly, actual object size on the heap is subject to low-level memory alignment done by a particular JVM implementation for a particular CPU type. It looks like a Long is 8 bytes of Object overhead, plus 8 bytes more for the actual long value. In contrast, Integer had an unused 4-byte hole, most likely because the JVM I use forces object alignment on an 8-byte word boundary.

其他容器也是昂贵的:

Multidimensional arrays: it offers another surprise.

Developers commonly employ constructs like int[dim1][dim2] in numerical and scientific computing.

In an int[dim1][dim2] array instance, every nested int[dim2] array is an Object in its own right. Each adds the usual 16-byte array overhead. When I don’t need a triangular or ragged array, that represents pure overhead. The impact grows when array dimensions greatly differ.

For example, a int[128][2] instance takes 3,600 bytes. Compared to the 1,040 bytes an int[256] instance uses (which has the same capacity), 3,600 bytes represent a 246 percent overhead. In the extreme case of byte[256][1], the overhead factor is almost 19! Compare that to the C/C++ situation in which the same syntax does not add any storage overhead.

String: a String‘s memory growth tracks its internal char array’s growth. However, the String class adds another 24 bytes of overhead.

For a nonempty String of size 10 characters or less, the added overhead cost relative to useful payload (2 bytes for each char plus 4 bytes for the length), ranges from 100 to 400 percent.

对准

class X { // 8 bytes for reference to the class definition

int a; // 4 bytes

byte b; // 1 byte

Integer c = new Integer(); // 4 bytes for a reference

}

一个天真的和将建议一个X的实例将使用17字节。但是,由于对齐(也称为填充),JVM以8个字节的倍数分配内存,因此,它将分配24个字节,而不是17个字节。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值