##java jol 工具类看内存布局
public class OutOfMemoryTest {
public static void main(String[] args) throws Exception {
List<MiBigObject> miBigObjects = new ArrayList<>(260000);
Field field = ArrayList.class.getDeclaredField("elementData");
field.setAccessible(true);
Object[] elementData = (Object[])field.get(miBigObjects);
MiBigObject miBigObject = new MiBigObject();
System.out.println(ClassLayout.parseInstance(elementData).toPrintable());
}
}
运行结果
[Ljava.lang.Object; object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 4 (object header: class) 0x00013190
12 4 (array length) 260000
12 4 (alignment/padding gap)
16 1040000 java.lang.Object Object;.<elements> N/A
Instance size: 1040016 bytes
Space losses: 4 bytes internal + 0 bytes external = 4 bytes total
Disconnected from the target VM, address: '127.0.0.1:53556', transport: 'socket'
Process finished with exit code 0
可以看出对象数组占用内存字节1040016字节
##源码
objArrayOop InstanceKlass::allocate_objArray(int n, int length, TRAPS) {
check_array_allocation_length(length, arrayOopDesc::max_array_length(T_OBJECT), CHECK_NULL);
int size = objArrayOopDesc::object_size(length);
Klass* ak = array_klass(n, CHECK_NULL);
objArrayOop o = (objArrayOop)Universe::heap()->array_allocate(ak, size, length,
/* do_zero */ true, CHECK_NULL);
return o;
}
static int object_size(int length) {
// This returns the object size in HeapWords.
uint asz = array_size(length);
uint osz = align_object_size(header_size() + asz);
assert(osz >= asz, "no overflow");
assert((int)osz > 0, "no overflow");
return (int)osz;
}
inline oop CollectedHeap::array_allocate(Klass* klass, int size, int length, bool do_zero, TRAPS) {
ObjArrayAllocator allocator(klass, size, length, do_zero, THREAD);
return allocator.allocate();
}
oop MemAllocator::allocate() const {
oop obj = NULL;
{
Allocation allocation(*this, &obj);
HeapWord* mem = mem_allocate(allocation);
if (mem != NULL) {
obj = initialize(mem);
} else {
// The unhandled oop detector will poison local variable obj,
// so reset it to NULL if mem is NULL.
obj = NULL;
}
}
return obj;
}
HeapWord* MemAllocator::mem_allocate(Allocation& allocation) const {
if (UseTLAB) {
HeapWord* result = allocate_inside_tlab(allocation);
if (result != NULL) {
return result;
}
}
return allocate_outside_tlab(allocation);
}
HeapWord* MemAllocator::allocate_outside_tlab(Allocation& allocation) const {
allocation._allocated_outside_tlab = true;
HeapWord* mem = Universe::heap()->mem_allocate(_word_size, &allocation._overhead_limit_exceeded);
if (mem == NULL) {
return mem;
}
NOT_PRODUCT(Universe::heap()->check_for_non_bad_heap_word_value(mem, _word_size));
size_t size_in_bytes = _word_size * HeapWordSize;
_thread->incr_allocated_bytes(size_in_bytes);
return mem;
}
##gdb调试栈 130002*8=1040016字节
#0 G1CollectedHeap::humongous_obj_allocate (this=0x7ffff00453d0, word_size=130002) at /home/yym/openjdk17/jdk17-master/src/hotspot/share/gc/g1/g1CollectedHeap.cpp:318
#1 0x00007ffff61d87ad in G1CollectedHeap::attempt_allocation_humongous (this=0x7ffff00453d0, word_size=130002)
at /home/yym/openjdk17/jdk17-master/src/hotspot/share/gc/g1/g1CollectedHeap.cpp:873
#2 0x00007ffff61d65ee in G1CollectedHeap::mem_allocate (this=0x7ffff00453d0, word_size=130002, gc_overhead_limit_was_exceeded=0x7ffff7bfe570)
at /home/yym/openjdk17/jdk17-master/src/hotspot/share/gc/g1/g1CollectedHeap.cpp:372
#3 0x00007ffff6779c88 in MemAllocator::allocate_outside_tlab (this=0x7ffff7bfe5d0, allocation=...)
at /home/yym/openjdk17/jdk17-master/src/hotspot/share/gc/shared/memAllocator.cpp:258
#4 0x00007ffff677a0b3 in MemAllocator::mem_allocate (this=0x7ffff7bfe5d0, allocation=...) at /home/yym/openjdk17/jdk17-master/src/hotspot/share/gc/shared/memAllocator.cpp:358
#5 0x00007ffff677a0f8 in MemAllocator::allocate (this=0x7ffff7bfe5d0) at /home/yym/openjdk17/jdk17-master/src/hotspot/share/gc/shared/memAllocator.cpp:365
#6 0x00007ffff6019669 in CollectedHeap::array_allocate (this=0x7ffff00453d0, klass=0x100058458, size=130002, length=260000, do_zero=true, __the_thread__=0x7ffff0028920)
at /home/yym/openjdk17/jdk17-master/src/hotspot/share/gc/shared/collectedHeap.inline.hpp:41
#7 0x00007ffff6344a2a in InstanceKlass::allocate_objArray (this=0x100041040, n=1, length=260000, __the_thread__=0x7ffff0028920)
at /home/yym/openjdk17/jdk17-master/src/hotspot/share/oops/instanceKlass.cpp:1349
#8 0x00007ffff685c1de in oopFactory::new_objArray (klass=0x100041040, length=260000, __the_thread__=0x7ffff0028920)
at /home/yym/openjdk17/jdk17-master/src/hotspot/share/memory/oopFactory.cpp:122
#9 0x00007ffff63686be in InterpreterRuntime::anewarray (current=0x7ffff0028920, pool=0x7fffd99039a8, index=7, size=260000)
at /home/yym/openjdk17/jdk17-master/src/hotspot/share/interpreter/interpreterRuntime.cpp:266
#10 0x00007fffe1023e51 in ?? ()
#11 0x00007fffe1023dc2 in ?? ()
#12 0x00000000ffba1060 in ?? ()
#13 0x00007ffff7bfe730 in ?? ()
#14 0x00007fffd9908f8a in ?? ()
#15 0x00007ffff7bfe790 in ?? ()
#16 0x00007fffd9acee38 in ?? ()
#17 0x0000000000000000 in ?? ()