java程序中的高内存使用率(使用数组进行大量递归)

时间:2016-05-04 21:04:45

标签: java

我遇到的问题一直困扰着我几天。我正在做大学校园,我必须乘以2个大数字(每个数字最多可达10000位),因此我必须使用数组。 我必须使用一个特殊的公式使用天真的分治法,它正在工作,我得到正确的输出问题虽然该程序的ram使用率达到715MB,而测试我的输出的大学服务器只允许小于10MB的峰值! 我使用visualVM来获取一些统计信息,它表明在main方法结束时我打开了超过25.000个int数组,这显然意味着垃圾收集器不会清理它们。我尝试通过array = null手动删除数组,但它没有任何效果。更重要的是,程序中的数组大小对ram的使用没有影响,如果我使所有数组大小为10000或者如果我使它们变小,那么ram的使用率仍然是715MB。我没有尝试过甚至使用RAM的1Kb差异。我做错了什么?

import java.util。*;

公共课Naloga2 {

static int firstNumberLength;
static int secondNumberLength;
static int count;   

public static void main(String[] args) {    

    firstNumberLength = 0;
    secondNumberLength = 0;

    start(args);    

    System.out.println("Check memory usage and press any key");
    Scanner scan = new Scanner(System.in);
    scan.nextLine();

}

static void printArray(int[] a, int length) {

    for(int i=0;i<length;i++) System.out.print(a[i]);
    System.out.println();

}

static void printArrayNoNewLine(int[] a, int length) {

    for(int i=0;i<length;i++) System.out.print(a[i]);       

}

static int[] obrniTabelo(int[] tabela, int dolzinaTabele) {

    int[] novaTabela = new int[firstNumberLength + secondNumberLength];

    for(int i=0;i<dolzinaTabele;i++) {                      
        novaTabela[i] = tabela[dolzinaTabele - i - 1];              
    }

    return novaTabela;

}

static void readNumbers(int[] a, int[] b) {

    Scanner sc = new Scanner(System.in);


    String temp1 = "1814760427359093701773634896055154238604621068079345503988844965147764988324706056377247443923778795928948605699104801900306908537904148935233121873094936503998915865745862371767010306054062906768898568957847355344002122176514654744790212626620584107994283130875249861052935175219132106429755509971192581933953801388381188460986660581979158129483917001271702223407654800335931472019985629221607213865018069283189966200621625300134";
    String temp2 = "97512060979417027247066473890437645860252983792423404628415959133594150264916901106891610016700858329869623573382829998749019896997745761637960733420798357562414782788848733769941600640359229331196534760613331886605807310229536529299047661042932723686940506490467693828359124032044766542882911974806517818312853119004786073768385133003204124346870416398337405003873260912959735781385513491033737150032844086069531948792576932151901897811096445945530418292434773408981209319417729967465446257427784080363848953538788259430643983374127862528899812266699138053211381274176090725067261872355977420957399650610409274997690573284775365452519492094199150332836530293736450846555043855394905294740708235099468050036111579819724363868989787277506605869758256547608040247461962450653542826639244219294087064008107664753142535552152880164752050308970662812876788273331513642358933315796998961151437131149920030780118660547331872894504653590764949555989125948482198399816531852334011945495558518939896596518131272300822293060394523495515862731265541258202053045616084735425799134171661329905235453695720851880506732702524221829703587444566936446048580047972702945614278702240636251666791566010549308512827456794434888225729025123511920552233844557238739513734443927750297099927757353661453279831551902974620243283691649185034824294607701567938075725970651517685420371143465190361476038554928265834067374093805712372282561321345651430079136538347289657425955000036298701183558407903511884604388721633166414508318158";

    firstNumberLength = temp1.length();
    secondNumberLength = temp2.length();

    for(int i=0;i<firstNumberLength;i++) a[i] = temp1.charAt(i) - 48;
    for(int i=0;i<secondNumberLength;i++) b[i] = temp2.charAt(i) - 48;

}

static void start(String[] args) {

    int a[] = new int[10000];
    int b[] = new int[10000];           

    readNumbers(a, b);  

    int aa[] = new int[firstNumberLength];
    int bb[] = new int[secondNumberLength];

    for(int i=0;i<firstNumberLength;i++) aa[i] = a[i];
    for(int i=0;i<secondNumberLength;i++) bb[i] = b[i];

    dv(aa, bb, "count");    
}   

static int[] steviloPlusSteviloRu (int[] a, int[] b, int[] tempDolzina) { 

    a = obrniTabelo(a, tempDolzina[0]);
    b = obrniTabelo(b, tempDolzina[1]);
    int prenos = 0;

    if(tempDolzina[0] < tempDolzina[1]) { 

        tempDolzina[0] = tempDolzina[1]; 

    }

    int limit = tempDolzina[1];

    for(int i=0;i<tempDolzina[1];i++) {

        a[i] = a[i] + b[i] + prenos;

        prenos = 0;

        if(a[i] > 9) {

            prenos = a[i] / 10;
            a[i] = a[i] % 10;               

        }

    }

    while(prenos > 0) {

        if(prenos > 9) System.out.println("prenos nad 9, error !");         

        a[limit] = a[limit] + prenos;
        prenos = 0;
        if(a[limit] > 9) { 

            prenos = a[limit] / 10;
            a[limit] = a[limit] % 10;

        }

        if(limit == tempDolzina[0]) tempDolzina[0]++;
        limit++;

    }       

    a = obrniTabelo(a, tempDolzina[0]);

    return a;

}

static int[] stevkaKratSteviloDv(int[] a, int b, int[] length) { // dv - mnozenje z stevko

    int prenos = 0;
    a = obrniTabelo(a, length[0]);

    for(int i=0;i<length[0];i++) {

        a[i] = a[i] * b + prenos;
        prenos = 0;
        if(a[i] > 9) {

            prenos = a[i] / 10;
            a[i] = a[i] % 10;

        }           
    }       

    if(prenos > 0 ) {

        if(prenos > 9) System.out.println("prenos vecji od 9 !!");
        a[length[0]] = prenos;
        length[0]++;

    }

    a = obrniTabelo(a, length[0]);

    return a;
}

static void dv(int[] a, int[] b, String m) { // dk

    int mode = 0;
    if(m.equals("count")) mode = 1;

    if(mode == 1) {

        printArray(a, firstNumberLength);   
        printArray(b, secondNumberLength);

    }       

    int[] dolzine = {firstNumberLength, secondNumberLength};                    
    int[] dolzina = {firstNumberLength, secondNumberLength};
    int[] len1 = {firstNumberLength};
    int[] len2 = {secondNumberLength};
    int[] len3 = new int[1];
    int[] rezultat = dvRek(a, b, len1, len2, len3, mode);

    rezultat = odstrani(rezultat, len3);

    if(mode == 0) {             
        printArray(rezultat, len3[0]);
    } else System.out.println(count);






}

static int[] subSet(int[] aa, int[] length, int mode) { // returns subset, depends on mode

    int dolzina = length[0];

    if(dolzina < 2) {           
        System.out.println("error, dolzina je " + dolzina);
        return aa;
    }

    int start = 0;
    int stop = dolzina / 2;
    if(mode == 1) { 

        start = dolzina / 2; 
        stop = dolzina;

    }

    int[] temp = new int[length[0]];        
    int index = 0;

    for(int i=start;i<stop;i++) {

        temp[index] = aa[i];
        index++;

    }

    length[0] = (stop - start);

    aa = null;      
    return temp;

}

static int[] dodajNicle(int[] aa, int[] length, int num) { // adds zeroes, basicly multiplying with 10^num

    int[] temp = new int[length[0] + num];  
    for(int i=0;i<length[0];i++) temp[i] = aa[i];   



    for(int i=0;i<num;i++) {            
        temp[length[0]] = 0;
        length[0]++;                
    }       

    aa = null;
    return temp;    

}

static int[] dopolni(int[] aa, int[] length, int num) { // adds num zeros at start and returns

    aa = obrniTabelo(aa, length[0]);

    int start = length[0];
    int end = start + num;


    for(int i=start;i<end;i++) aa[i] = 0;
    length[0] = length[0] + num;

    aa = obrniTabelo(aa, length[0]);

    return aa;

}

static int[] odstrani(int[] aa, int[] length) { // removes zeros from beginning

    aa = obrniTabelo(aa, length[0]);

    for(int i=(length[0]-1);i>0;i--)    
        if(aa[i] == 0) length[0]--;
        else break; 

    aa = obrniTabelo(aa, length[0]);


    return aa;

}

static int[] dvRek (int[] a, int[] b, int[] lengthA, int[] lengthB, int[] lengthC, int mode) {

    a = odstrani(a, lengthA);
    b = odstrani(b, lengthB);

    if(mode == 0)   {                   
        printArrayNoNewLine(a, lengthA[0]);
        System.out.print(" ");
        printArray(b, lengthB[0]);
    }

    if(lengthA[0] == 1) {

        if(a[0] == 0) {

            lengthC[0] = 1;             
            return new int[1];
        }           

        int temp = lengthB[0];

        int minus = 0;
        for(int i=0;i<temp;i++) {               
            if(b[i] == 0) minus++;
            if(b[i] > 0) break;             
        }

        count = count + temp - minus;

        b = stevkaKratSteviloDv(b, a[0], lengthB);          
        lengthC[0] = lengthB[0];
        lengthB[0] = temp;
        return b;

    } else if (lengthB[0] == 1) {


        if(b[0] == 0) {

            lengthC[0] = 1;             
            return new int[1];

        }           

        int temp = lengthA[0];



        int minus = 0;
        for(int i=0;i<temp;i++) {               
            if(a[i] == 0) minus++;
            if(a[i] > 0) break;             
        }

        count = count + temp - minus;       

        a = stevkaKratSteviloDv(a, b[0], lengthA);          
        lengthC[0] = lengthA[0];

        return a;

    } else {    

        if(lengthA[0] > lengthB[0]) {

            b = dopolni(b, lengthB, (lengthA[0] - lengthB[0])); 

        }                               
        else if (lengthA[0] < lengthB[0]) { 

            a = dopolni(a, lengthA, (lengthB[0] - lengthA[0]));

        }

        int[] a1Len = { lengthA[0] };
        int[] a0Len = { lengthA[0] }; 
        int[] b1Len = { lengthB[0] };
        int[] b0Len = { lengthB[0] };

        int[] a1 = subSet(a, a1Len, 0);
        int[] a0 = subSet(a, a0Len, 1);
        int[] b1 = subSet(b, b1Len, 0);
        int[] b0 = subSet(b, b0Len, 1);


        a = null;
        b = null;

        int[] temp = new int[1];
        int[] tempp = new int[1];


        temp[0] = b0Len[0]; 
        tempp[0] = a0Len[0];
        int[] a0b0 = dvRek(a0, b0, tempp, temp, lengthC, mode);
        int[] a0b0Len = { lengthC[0] };



        temp[0] = b1Len[0];     
        tempp[0] = a0Len[0];
        int[] a0b1 = dvRek(a0, b1, tempp, temp, lengthC, mode);
        int[] a0b1Len = { lengthC[0] };




        //a1b0          
        temp[0] = b0Len[0];     
        tempp[0] = a1Len[0];
        int[] a1b0 = dvRek(a1, b0, tempp, temp, lengthC, mode);
        int[] a1b0Len = { lengthC[0] };




        //a1b1  
        temp[0] = b1Len[0];     
        tempp[0] = a1Len[0];
        int[] a1b1 = dvRek(a1, b1, tempp, temp, lengthC, mode);
        int[] a1b1Len = { lengthC[0] };



        int n = lengthA[0];
        if(lengthB[0] > n) n = lengthB[0];

        if(n % 2 != 0) n++;

        int[] temp1 = dodajNicle(a1b1, a1b1Len, n );



        int[] dolzine = {a0b1Len[0], a1b0Len[0]};       
        int[] temp2 = steviloPlusSteviloRu(a0b1, a1b0, dolzine);



        temp2 = dodajNicle(temp2, dolzine, (n/2) );




        int[] dolzine1 = {a1b1Len[0], dolzine[0]};          
        int[] temp3 = steviloPlusSteviloRu(temp1, temp2, dolzine1);



        int[] dolzine2 = {dolzine1[0], a0b0Len[0] };
        int[] temp4 = steviloPlusSteviloRu(temp3, a0b0, dolzine2);


        lengthC[0] = dolzine2[0];               

        a = null;
        b = null;
        a0b0 = null;
        a1b0 = null;
        a0b1 = null;
        a1b1 = null;
        a0 = null;
        a1 = null;
        b0 = null;
        b1 = null;
        lengthA = null;
        lengthB = null;
        lengthC = null;
        temp = null;
        tempp = null;
        dolzine = null;
        dolzine1 = null;
        dolzine2 = null;
        temp1 = null;
        temp2 = null;
        temp3 = null;



        return temp4;

    }   

}

}

0 个答案:

没有答案