search

Home  >  Q&A  >  body text

java - ArrayList memory allocation, cross-generation reference gc issue

What is the memory allocation of ArrayList in JVM?

假设List<BigObject> list = new ArrayList<>(); 

private static class BigObject{
        private byte[] foo;

        BigObject(){
            foo = new byte[20 * 1024];
        }
    }

Continuously add BigObject, Is the reference relationship as follows?

Then ygc occurs. Did BigObject enter the old area? If the arrayList object does not enter the old area, wouldn't there be a cross-generation reference? If it enters, then after ygc, obj = new BigObject() is allocated in the new generation, and then list.add(obj), wouldn't there be a reference to the old->young area? What is the memory allocation like?

Origin of the problem

Run the following code:
Parameters:/jdk1.7.0_79.jdk/bin/java -Xmx500M -Xms500M -Xmn200M -XX: UseConcMarkSweepGC -XX: UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=90 -XX: PrintGCApplicationConcurrentTime - XX: PrintGCApplicationStoppedTime -XX: PrintHeapAtGC -XX: PrintGCDateStamps -XX: PrintHeapAtGC -XX: PrintGCDateStamps -verbose:gc -XX: PrintGCDetails -Xloggc:/Users/*/temp/test.gc.log

import java.util.ArrayList;
import java.util.List;

/**
 * @author ***
 * @time 2017-04-19-11:14
 */
public class CrossReference {
    private static int unit = 20 * 1024;

    public static void main(String[] args) {
        allocate();

        try {
            Thread.sleep(1000);
            System.out.println("allocate end************");
            Thread.sleep(100000);
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    private static void allocate(){
        List<BigObject> list = new ArrayList<>();
        int size = 1024 * 1024 * 400;
        int len = size / unit;

        for( int i = 0; i < len; i++){

            BigObject bigObject = new BigObject();
            list.add(bigObject);
        }
    }

    private static class BigObject{
        private byte[] foo;

        BigObject(){
            foo = new byte[unit]; //
        }
    }


}

Looking at gc.log, it will appear that after executing the allocate() method, the old area is still occupied more than 90%, and CMS GC is continuously performed but cannot be recycled.

黄舟黄舟2772 days ago901

reply all(1)I'll reply

  • 高洛峰

    高洛峰2017-05-17 10:09:27

    I recently saw two articles that may be useful to you:

    http://zhuanlan.51cto.com/art...
    http://zhuanlan.51cto.com/art...

    reply
    0
  • Cancelreply