Maison  >  Questions et réponses  >  le corps du texte

java - Allocation de mémoire ArrayList, problème GC de référence inter-génération

Quelle est l'allocation de mémoire d'ArrayList dans la JVM ?

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

private static class BigObject{
        private byte[] foo;

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

Ajoutez continuellement BigObject, La relation de référence est-elle la suivante ?

Ensuite, ygc se produit. BigObject est-il entré dans l'ancienne zone ? Si l'objet arrayList n'entre pas dans l'ancienne zone, n'y aurait-il pas une référence inter-génération ? S'il entre, alors obj = new BigObject() est alloué dans la nouvelle génération après ygc, puis list.add(obj), n'y aurait-il pas une référence à la zone old->young ? comme?

L'origine du problème

Exécutez le code suivant :
Paramètres : /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]; //
        }
    }


}

En regardant gc.log, il apparaîtra qu'après l'exécution de la méthode allocate(), l'ancienne zone est toujours occupée à plus de 90 % et le CMS GC est effectué en continu mais ne peut pas être recyclé.

黄舟黄舟2712 Il y a quelques jours849

répondre à tous(1)je répondrai

  • 高洛峰

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

    J'ai vu récemment deux articles qui pourraient vous être utiles :

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

    répondre
    0
  • Annulerrépondre