简体   繁体   English

java,OutOfMemoryError:Java堆空间

[英]java, OutOfMemoryError: Java heap space

This class is designed to determine the language of a text; 此类旨在确定文本的语言。 the user has to enter 4 text in english, danish, italian and latin, and then the text whose language he wants to determine. 用户必须以英文,丹麦文,意大利文和拉丁文输入4个文本,然后输入他想确定其语言的文本。 The console says 控制台说

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at Riconoscimento2.creaTabellaTotale(Riconoscimento2.java:365)
    at Riconoscimento2.main(Riconoscimento2.java:25)

I use eclipse, in Run Configurations - Arguments I wrote -Xms2g-Xmx3g. 我在运行配置-我写的-Xms2g-Xmx3g参数中使用了eclipse。 I don't understand where is the problem. 我不明白问题出在哪里。

The code is 该代码是

 import java.io.*;

import java.util.*;

import prog.io.*;

public class Riconoscimento2 {

public static void main(String[] args) {
            char[] array = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', ' '};
            System.out.println("Immetti l'intero n per il calcolo degli n-grammi ");  // questa istruzione richiede di immettere l'intero n 
            BufferedReader sc = new BufferedReader(new InputStreamReader(System.in));
            Scanner in = new Scanner(System.in);
            int n = in.nextInt();
            StringBuffer[] tabellaTotale = creaTabellaTotale(n, array);

            System.out.println("Immetti un testo in inglese, che poi verrà utilizzato come paradigma. Ricordati di non inserire rientri a capo."); // con questa e le successive istruzioni si chiede di immettere dei testi campioni scritti in inglese, danese, italiano, latino

             String testo_inglese ="";
             try{
                 testo_inglese = sc.readLine();
             }catch(IOException e1){
                 System.out.println("Input non corretto. Immetti un testo in inglese. ");
             }




            System.out.println("Immetti un testo in danese, che poi verrà utilizzato come paradigma. Ricordati di non inserire rientri a capo.");



             String testo_danese ="";
             try{
                 testo_danese = sc.readLine();
             }catch(IOException e1){
                 System.out.println("Input non corretto. Immetti un testo in danese. ");
             }






            System.out.println("Immetti un testo in italiano, che poi verrà utilizzato come paradigma. Ricordati di non inserire rientri a capo.");



             String testo_italiano ="";
             try{
                 testo_italiano = sc.readLine();
             }catch(IOException e1){
                 System.out.println("Input non corretto. Immetti un testo in italiano. ");
             }









            System.out.println("Immetti un testo in latino, che poi verrà utilizzato come paradigma. Ricordati di non inserire rientri a capo.");



             String testo_latino ="";
             try{
                 testo_latino = sc.readLine();
             }catch(IOException e1){
                 System.out.println("Input non corretto. Immetti un testo in latino. ");
             }



            System.out.println("Immetti il testo di cui vuoi determinare la lingua. Ricordati di non inserire rientri a capo.");



             String testo ="";
             try{
                 testo = sc.readLine();
             }catch(IOException e1){
                 System.out.println("Input non corretto. Immetti il testo di cui vuoi determinare la lingua. ");
             }



            StringBuffer testo_inglese_formattato = formatta(testo_inglese);   // testo_inglese_formattato rappresenta il testo inglese immesso dall'utente in cui i caratteri non alfabetici sono stati trasformati in spazi 
                                                                               // e sono stati rimossi gli spazi multipli. Lo stesso discorso vale per le righe successive.
            StringBuffer testo_danese_formattato = formatta(testo_danese);
            StringBuffer testo_italiano_formattato = formatta(testo_italiano);
            StringBuffer testo_latino_formattato = formatta(testo_latino);
            StringBuffer testo_formattato = formatta(testo);
            if ( n > testo.length() ) // questo controllo serve per gestire il caso in cui l'intero immesso dall'utente è più lungo della lunghezza del testo
            System.out.println("Hai immesso un intero troppo grande se confrontato al testo");
            else { 

                int[] lista_testo = creaLista(testo_formattato, tabellaTotale, n)   ;                   // questa istruzione crea la sequenza delle occorrenze degli n-grammi presenti nel testo immesso dall'utente e poi formattato
                int[] lista_inglese = creaLista(testo_inglese_formattato, tabellaTotale, n) ;
                int[] lista_danese = creaLista(testo_danese_formattato, tabellaTotale, n)   ;
                int[] lista_italiano = creaLista(testo_italiano_formattato, tabellaTotale, n );
                int[] lista_latino = creaLista(testo_latino_formattato, tabellaTotale, n)   ;
                double scarto_inglese = calcolaScarto(tabellaTotale, testo_formattato, testo_inglese_formattato, n);
                double scarto_danese = calcolaScarto( tabellaTotale, testo_formattato, testo_danese_formattato, n);
                double scarto_italiano = calcolaScarto(tabellaTotale, testo_formattato, testo_italiano_formattato, n);
                double scarto_latino = calcolaScarto(tabellaTotale, testo_formattato, testo_latino_formattato, n);
                double[] v = {scarto_inglese, scarto_danese, scarto_italiano, scarto_latino};
                double min = v[0];                    
                for (int j =0; j<4; j++){    // una volta calcolati gli scarti, si determina lo scarto minimo; il programma 
                    if ( v[j]<min )          // comunicherà poi all'utente che la lingua del testo è quella che ha dato lo scarto minimo.
                        min = v[j];          // Chiaramente si tratta di un procedimento probabilistico, tanto più efficiente quanto più i testi forniti sono lunghi.
                }

                String lingua = "italiano";
                if ( min == v[0])
                    lingua = "inglese";

                if ( min == v[1])
                    lingua = "danese";

                if ( min == v[2])
                    lingua = "italiano";

                if ( min == v[3])
                    lingua = "latino";

                System.out.println("E' molto probabile che il testo inserito sia scritto in " + lingua);
            }

            in.close();
        }

        public static StringBuffer  formatta (String s){  // questo metodo serve per formattare il testo, trasformando i caratteri non alfabetici in spazi
                                                          // ed eliminando gli spazi multipli

        s = s.toLowerCase();
        StringBuffer b = new StringBuffer();
        int m = s.length();
        int conta_spazi = 0;
        StringBuffer h = new StringBuffer(s);
        for (int i = 0; i < m ; i++ ){
        switch(h.charAt(i)) {
        case 'a':
            break;

        case 'A':
            break;

        case 'b':
            break;

        case 'B':
            break;

        case 'c':
            break;

        case 'C':
            break;


        case 'd':
            break;

        case 'D':
            break;

        case 'e':
            break;

        case 'E':
            break;

        case 'f':
            break;

        case 'F':
            break;

        case 'g':
            break;

        case 'G':
            break;

        case 'h':
            break;

        case 'H':
            break;

        case 'i':
            break;

        case 'I':
            break;

        case 'j':
            break;

        case 'J':
            break;

        case 'k':
            break;

        case 'K':
            break;

        case 'l':
            break;

        case 'L':
            break;

        case 'm':
            break;

        case 'M':
            break;

        case 'n':
            break;

        case 'N':
            break;

        case 'o':
            break;

        case 'O':
            break;

        case 'p':
            break;

        case 'P':
            break;

        case 'q':
            break;

        case 'Q':
            break;

        case 'r':
            break;

        case 'R':
            break;

        case 's':
            break;

        case 'S':
            break;

        case 't':
            break;

        case 'T':
            break;

        case 'u':
            break;

        case 'U':
            break;

        case 'v':
            break;

        case 'V':
            break;

        case 'w':
            break;

        case 'W':
            break;

        case 'x':
            break;

        case 'X':
            break;

        case 'y':
            break;

        case 'Y':
            break;

        case 'z':
            break;

        case 'Z':
            break;

        default:
            h.setCharAt(i, ' ');


        }
        }
        for (int i = 0; i < m ; i++ ){

            if ( h.charAt(i) == ' ' )
            conta_spazi++;
            else
                conta_spazi = 0;

            if ( conta_spazi <= 1)
            b = b.append(h.charAt(i));

          }

        return b;

        }


        public static int[] creaLista (StringBuffer str , StringBuffer[] tabella, int n){   

            int[] tavolaOccorrenze = new int[pow(27,n)];

            for(int i =0; i < pow(27, n); i++ ) 
            tavolaOccorrenze[i] = numeroOccorrenze(str, tabella[i]);



            return tavolaOccorrenze;

        }

        public static double calcolaFrequenza( int[] tavolaOccorrenze, StringBuffer testo, String st, int n){ 

            double tot = 0;
            for(int i =0; i < pow(27, n); i++ )
                tot += tavolaOccorrenze[i];
            double frequenza = 0;
            double occorrenze_st = numeroOccorrenze(testo, new StringBuffer(st));
            return occorrenze_st / tot;

        }

        public static double calcolaScarto (StringBuffer[] tabella, StringBuffer testo1, StringBuffer testo2, int n){  

            double scarto = 0;
            int[] tavolaOccorrenze1 = creaLista(testo1, tabella, n);
            int[] tavolaOccorrenze2 = creaLista(testo2, tabella, n);
            for(int i =0; i < pow(27, n); i++ )
                scarto += Math.pow(calcolaFrequenza(tavolaOccorrenze1, testo1, tabella[i].toString(), n)-calcolaFrequenza(tavolaOccorrenze2, testo2, tabella[i].toString(), n), 2);

            return scarto;
        }


        public static StringBuffer[] creaTabellaTotale(int n, char[] a) {   /* questa funzione crea la tabella che definisce l'ordine degli n-grammi*/


             StringBuffer[] tabella = new StringBuffer[ pow(27, n)];

             for(int h = 1; h <= n ; h++){
                for(int u =0; u < pow ( 27, h-1); u++){

                for (int j = 0; j<27; j++){

                    for( int x =pow(27, n-h+1)*u + pow(27, n-h)*j; x< pow(27, n-h+1)*u + pow(27, n-h)*(j+1); x++)
                        tabella[x] = tabella[x].append(a[j]);
                }

                }

             }

             return tabella;
        }


        public static int pow(int a, int b){                                            
              int tot = 1;
              for(int i =0; i<b ; i++)
              tot = a * tot ;
              return tot;
             }


         public static int numeroOccorrenze ( StringBuffer testo, StringBuffer parola){   
             int tot =0;
             if(parola.length() > testo.length())
                System.out.println("L' n-gramma da cercare è troppo lungo in confronto al testo inserito ");
             else{
                int n = parola.length();
                for(int i = 0; i <= testo.length() - n; i++ ){
                    if(testo.substring(i,i+n) == parola.toString())
                        ++tot;
                }


             }

             return tot;
            }



     }

This line throws the exception: 这行抛出异常:

StringBuffer[] tabella = new StringBuffer[pow(27, n)];

why? 为什么? well, your function pow(a, b) is correct but the n variable is a bit off. 好吧,您的函数pow(a, b)是正确的,但是n变量有点不正确。 You are reading it from there: 您正在从那里阅读它:

n = in.read();

This will give you the ascii code of the character you enter in the console, and not the number. 这将为您提供您在控制台中输入的字符的ASCII码,而不是数字。 If you write "1", then n will be 49, and pow(27, 49) is way too much. 如果您输入“ 1”,则n将为49,而pow(27,49)太多了。

To simply read the input of the user, you should try to use java.util.Scanner instead, to get the number that the user inputs. 为了简单地读取用户的输入,您应该尝试使用java.util.Scanner来获取用户输入的数字。

For starters, you're not closing your input stream, I don't see a call to in.close() anywhere. 对于初学者,您不会关闭输入流,在任何地方都看不到对in.close()的调用。 Why don't you try adding that, saving, then shutting down your running jre to release those input stream connections that could still be in memory somewhere, and running this again? 为什么不尝试添加,保存然后关闭正在运行的jre,以释放可能仍在内存中的那些输入流连接,然后再次运行呢?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM