2016-01-22 3 views
0

У меня есть очень простая программка, которая показана нижеОгромного потребления памяти нитей

Main-Method: 

Thread.sleep(10000); 

MyThread[] threads=new MyThread[16]; 

for(int i=0;i<16;i++){ 
    threads[i]=new MyThread(); 
} 

for(int i=0;i<16;i++){ 
    threads[i].start(); 
} 

for(int i=0;i<16;i++){ 
    threads[i].join(); 
} 






Threadclass: 

public class MyThread extends Thread{ 
byte[][] queue = new byte[125][]; 

public void run() { 

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

    byte[] tempbyte=new byte[20]; 
    for(int i1=0;i1<20;i1++){ 
     tempbyte[i1]=(byte) 255; 
    } 
    queue[i]=tempbyte; 
    } 

    try { 
     Thread.sleep(3000000); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 
} 

Так основно каждый поток создает 125 массивов 20-байт. С 16 потоками должно быть 40.000 байт (16 * 125 * 20). Теперь возникает проблема: Когда я начинаю эту программку со следующим VM-аргументами:

-Xms14000m -XX: NewSize = 10000m

и запустить

jcstat -gC#PID

то он показывает около 460 мб для eden (ЕС). Когда основной поток запущен, и я снова jstat, он показывает около 3000 мб! Какая причина для большой кучи? Я уже сделал heapdump, и источником кучи-отходов являются множество массивов int [] и char []. Они не привязаны, поэтому я не могу их отслеживать.

+0

EDIT: Я думаю, что эти темы связаны: http://stackoverflow.com/questions/17145228/track-down-allocations-of-int и http://stackoverflow.com/questions/7304665/ objects-with-no-references-in-hprof – Jens

ответ

0

Размер кучи определяется jvm, он отслеживает выделенную память и частоту распределения (и многое другое) и использует некоторые сложные методы для ее вычисления. Прошедшие аргументы рассматриваются как предложения не как конфигурации, поэтому jvm может игнорировать -Xms14000m -XX:NewSize=10000m. Вы не можете ожидать, что размер кучи будет точно определенным числом из ваших переменных.

Я не вижу «утечку памяти» в коде, который вы указали, это все?

Также я предлагаю вам использовать виртуальную виртуальную машину Java для отслеживания потребления памяти, расположенной в папке bin jdk.

+0

Спасибо за ваш ответ. Я думаю, что я неправильно выразил размеры кучи. Перед всеми потоками начать: Доступные кучи: 14GB, использовано кучу: 460MB После всех нитей начали (в Thread.sleep (3000000)): Ava. куча: 14 ГБ, Usedheap: 3 ГБ. Я уже использовал visualVM (и Eclipse MAT, а также JProfiler). Как уже упоминалось, все они показывают большие массивы int [] и char []. Я думаю, что эти массивы из JVM, потому что ни один объект, который я создал, не ссылается на них. Когда я разбираю кучи с помощью parseHeapDump.sh -keep_unreachable_objects (Eclipse MAT), то я могу их видеть. И да, это целый код – Jens

Смежные вопросы