2017-05-17 1 views
2

Je travaille sur tester comment une application Java gère sous contrainte. L'un des scénarios que je cherche à tester est celui où la JVM est vandalisée en raison de la récupération de place constante. Une des conditions que j'ai vu est qu'une fuite de mémoire lente va amener la JVM à entrer dans un état où elle passera continuellement plus de 95% de son temps processeur à effectuer des GC. Dans cet état, la machine virtuelle Java n'exécute pas de code d'application. Je suis intéressé par l'écriture d'une méthode Java qui, lorsqu'elle est exécutée, induira ce type de comportement GC. Comment pourrais-je faire ça?Force JVM à thrash en raison de la constante GC

+0

Je suppose que créer beaucoup d'objets? – shmosel

+0

Il ne suffit pas de créer beaucoup d'objets. Vous devez également vous assurer qu'un pourcentage d'entre eux "fuient"; c'est-à-dire garder une référence afin que les objets qui fuient restent accessibles. –

+0

@shmosel Yup, créez beaucoup d'objets non-GC'ables, puis, lorsque la mémoire est (presque) pleine, commencez à créer des objets GC'able, pour provoquer des exécutions continues du GC. Voir l'exemple dans [ma réponse] (http://stackoverflow.com/a/44036245/5221149), en suivant votre suggestion. – Andreas

Répondre

3

Créer un grand nombre d'objets jusqu'à ce que OutOfMemoryError se produise, puis en libérer quelques-uns. Entrez maintenant une boucle d'allocation et de libération.

Exemple

final int BLOCK_SIZE = 1000000; 
List<byte[]> list = new LinkedList<>(); 
try { 
    for (;;) { 
     list.add(new byte[BLOCK_SIZE]); 
     if (list.size() % 1000 == 0) 
      System.out.println(list.size()); 
    } 
} catch (@SuppressWarnings("unused") OutOfMemoryError e) { 
    // Ignore 
} 
list.remove(0); // free some memory 
System.out.println((list.size() + 1) + " Memory full"); 
for (int i = 0; i < 15; i++) { 
    System.out.println(i); 
    list.add(new byte[BLOCK_SIZE]); 
    list.remove(0); 
} 
System.out.println("Done"); 

sortie (courir avec -XX:+PrintGC -XX:+PrintGCTimeStamps)

0.089: [GC (Allocation Failure) 131241K->128483K(502784K), 0.0231605 secs] 
0.123: [GC (Allocation Failure) 259971K->259265K(634368K), 0.0280219 secs] 
0.151: [Full GC (Ergonomics) 259265K->259088K(858112K), 0.0481911 secs] 
0.233: [GC (Allocation Failure) 522083K->522044K(858112K), 0.0533938 secs] 
0.286: [Full GC (Ergonomics) 522044K->521794K(1285632K), 0.0087057 secs] 
0.315: [GC (Allocation Failure) 784782K->784749K(1454592K), 0.0514033 secs] 
0.366: [Full GC (Ergonomics) 784749K->784500K(1792512K), 0.0095001 secs] 
1000 
0.425: [GC (Allocation Failure) 1215843K->1215427K(1792512K), 0.0880220 secs] 
0.513: [Full GC (Ergonomics) 1215427K->1215181K(2387968K), 0.0134368 secs] 
0.558: [GC (Allocation Failure) 1646521K->1646108K(2724352K), 0.0873853 secs] 
0.646: [Full GC (Ergonomics) 1646108K->1645863K(3247616K), 0.0134679 secs] 
2000 
0.754: [GC (Allocation Failure) 2413882K->2413709K(3247616K), 0.1432810 secs] 
0.897: [Full GC (Ergonomics) 2413709K->2413471K(4247552K), 0.0180889 secs] 
3000 
0.972: [GC (Allocation Failure) 3181488K->3181318K(4877312K), 0.1505734 secs] 
1.122: [Full GC (Ergonomics) 3181318K->3181080K(5798400K), 0.0207634 secs] 
4000 
1.321: [GC (Allocation Failure) -- 4579352K->5802028K(5824000K), 0.2306780 secs] 
1.552: [Full GC (Ergonomics) 5802028K->4574691K(7000064K), 0.0412160 secs] 
5000 
1.683: [GC (Allocation Failure) -- 5802028K->6977828K(7000064K), 0.2326833 secs] 
1.915: [Full GC (Ergonomics) 6977828K->5793490K(7000064K), 0.0411068 secs] 
6000 
7000 
2.043: [Full GC (Ergonomics) 6977828K->6974201K(7000064K), 0.1676370 secs] 
2.211: [Full GC (Ergonomics) 6977828K->6977131K(7000064K), 0.0248826 secs] 
2.236: [Full GC (Allocation Failure) 6977131K->6977119K(7000064K), 1.0004488 secs] 
7144 Memory full 
0 
3.237: [Full GC (Ergonomics) 6977816K->6976142K(7000064K), 1.1094352 secs] 
1 
4.346: [Full GC (Ergonomics) 6977816K->6976142K(7000064K), 1.0821330 secs] 
2 
5.429: [Full GC (Ergonomics) 6977816K->6976142K(7000064K), 1.0057587 secs] 
3 
6.435: [Full GC (Ergonomics) 6977816K->6976142K(7000064K), 0.9934119 secs] 
4 
7.428: [Full GC (Ergonomics) 6977816K->6976142K(7000064K), 1.0060575 secs] 
5 
8.435: [Full GC (Ergonomics) 6977816K->6976142K(7000064K), 0.9925522 secs] 
6 
9.427: [Full GC (Ergonomics) 6977816K->6976142K(7000064K), 1.0048095 secs] 
7 
10.432: [Full GC (Ergonomics) 6977816K->6976142K(7000064K), 0.9968477 secs] 
8 
11.430: [Full GC (Ergonomics) 6977665K->6976142K(7000064K), 1.0109500 secs] 
9 
12.441: [Full GC (Ergonomics) 6977480K->6976142K(7000064K), 1.0050952 secs] 
10 
13.446: [Full GC (Ergonomics) 6977361K->6976142K(7000064K), 0.9977489 secs] 
11 
14.444: [Full GC (Ergonomics) 6977283K->6976142K(7000064K), 1.0184425 secs] 
12 
15.463: [Full GC (Ergonomics) 6977232K->6976142K(7000064K), 1.06secs] 
13 
16.523: [Full GC (Ergonomics) 6977199K->6976142K(7000064K), 1.0214882 secs] 
14 
17.545: [Full GC (Ergonomics) 6977178K->6976142K(7000064K), 1.0136330 secs] 
Done 

Comme on peut le voir, la première boucle est rapide, environ 7000 itérations en 2 secondes. Une fois la mémoire saturée, la seconde boucle nécessite une exécution GC pour chaque itération, et chaque exécution GC dure environ 1 seconde.

+0

Un bel exemple! –