openjdk17 从C++ 源码角度看 对象数组内存分配的字节数

发布于:2025-02-11 ⋅ 阅读:(20) ⋅ 点赞:(0)

##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 ?? ()