Size of Huge Objects directly allocated to Old Generation

前端 未结 3 1480
轮回少年
轮回少年 2020-11-28 06:09

Recently I\'ve been reading about object allocations in different generations in Java. Most of the times new objects are allocated in Eden (part of Young Generation) and the

相关标签:
3条回答
  • 2020-11-28 06:22

    JVM flags:

    -Xms1G -Xmx1G -Xmn500m -XX:PretenureSizeThreshold=100000000 -XX:+PrintGCDetails

    By fixing the young generation size to 500MB, eden comes around 384MB, So any object greater than 384MB goes directly into OldGen and object less than 384MB is allocated in Eden itself. You can find the generation usages below

    byte[] array = new byte[400*1024*1024];

    PSYoungGen      total 448000K, used 30720K  
        eden space 384000K, 8% used  
        from space 64000K, 0% used  
        to   space 64000K, 0% used      
     ParOldGen       total 536576K, used 409600K  
       object space 536576K, 76% used 
    

    byte[] array = new byte[300*1024*1024];

     PSYoungGen      total 448000K, used 337920K  
      eden space 384000K, 88% used  
      from space 64000K, 0% used  
      to   space 64000K, 0% used  
     ParOldGen       total 536576K, used 0K 
      object space 536576K, **0% used** 
    

    For 400MB allocation, eden usage is 8% where as old gen usage is 76% For 300MB allocation, eden usage is 88% where as old gen usage is 0% So its clear that all the objects whose size is greater than the eden will be allocated directly into old gen.

    Thanks apangin & Jigar for your valuable insights :)
    I think -XX:PretenureSizeThreshold is not considered at all.

    0 讨论(0)
  • 2020-11-28 06:42

    You can set the limit by using following flag

    XX:PretenureSizeThreshold=size
    

    its default value is 0 I assume that by default if you don't set it it doesn't get considered with value=0, that means by default there is no maximum value that acts as threshold, by default object gets promoted only based on number of GC survival

    HotSpot version

    java version "1.7.0_45"
    Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
    Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
    

    to get all vm options (supported) you can run

    java -XX:+PrintVMOptions -XX:+AggressiveOpts -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal  -version
    

    and then you can refer to hotspot vm option document or google particular option if not listed


    byte[] array = new byte[300*1024*1024];
    
    for(MemoryPoolMXBean memoryPoolMXBean: ManagementFactory.getMemoryPoolMXBeans()){
        System.out.println(memoryPoolMXBean.getName());
        System.out.println(memoryPoolMXBean.getUsage().getUsed());
    }
    

    outputs:

    $ java -Xmx1500m -Xms1500m -Xmn500m -XX:PretenureSizeThreshold=100000000 -XX:+PrintGCDetails JVMMemoryInspection
    Code Cache
    393664
    PS Eden Space
    330301752
    PS Survivor Space
    0
    PS Old Gen
    0
    PS Perm Gen
    2749520
    
    0 讨论(0)
  • 2020-11-28 06:44

    The maximum size of an object HotSpot JVM may allocate in young generation is nearly as large as the size of Eden (YoungGen minus two Survivor spaces).

    That's how the allocation rougly looks like:

    1. Use Thread Local Allocation Buffer (TLAB), if tlab_top + size <= tlab_end
      This is the fastest path. Allocation is just the tlab_top pointer increment.
    2. If TLAB is almost full, create a new TLAB in Eden and retry in a fresh TLAB.
    3. If TLAB remaining space is not enough but is still to big to discard, try to allocate an object directly in Eden. Allocation in Eden is also a pointer increment (eden_top + size <= eden_end) using atomic operation, since Eden is shared between all threads.
    4. If allocation in Eden fails, a minor collection typically occurs.
    5. If there is not enough space in Eden even after Young GC, an attempt to allocate directly in Old generation is made.
    0 讨论(0)
提交回复
热议问题