Heap java administration

4

I'm doing a copy paste, from excel to JTable . The problem is that it consumes too much memory. I have looked for solutions to do that procedure in other ways but I can not find it. If anyone knows another way to do it, I appreciate it because I've been looking for everything for 1 month and trying everything.

The code is as follows:

public void pegar() {
    Runnable miRunnable = new Runnable() {
        @Override
        public void run() {
            try {
                Clipboard clp = Toolkit.getDefaultToolkit().getSystemClipboard();

                String total = (String) (clp.getContents(this).getTransferData(DataFlavor.stringFlavor));
                clp=null;
                StringTokenizer stk1 = new StringTokenizer(total, "\n");
                //dejo total en null
                total = null;
                System.gc();
                dtm.setRowCount(stk1.countTokens());
                int max = 0;
                jProgressBar1.setMaximum(stk1.countTokens());

                ArrayList<String>lista = new ArrayList<>();
                for (int i = 0; stk1.hasMoreTokens(); i++) {

                    String valor = stk1.nextToken();
                    for (int j = 0; j < 36; j++) {
                        valor = valor.replaceAll("\t\t", "\t \t");
                    }

                    lista.add(valor);

                }
                //dejo el clipboard en null para liberar memoria

                stk1 = null;
                System.gc();
                int size = lista.size();
                //  System.out.println(lista.);

                for (int i = 0; i < size; i++) {
                    StringTokenizer stk2 = new StringTokenizer(lista.get(0), "\t");
                    for (int j = 0; stk2.hasMoreElements(); j++) {
                        String value = stk2.nextToken();
                        jTable1.setValueAt(value, i, j);
                    }
                    lista.remove(0);

                    max++;
                    System.out.println(max);
                    jProgressBar1.setValue(max);
                }
                lista = null;
                Runtime runtime = Runtime.getRuntime();

                System.out.println("");
                jProgressBar1.setForeground(new Color(51,0,102));
                System.out.println("me voy a poner en pausa");
                Thread.sleep(3000);
                System.out.println("voy a limpiar");

                runtime.gc();
            } catch (UnsupportedFlavorException|IOException|InterruptedException ex) {

            }
        }
    };
    System.gc();
    hilo = new Thread (miRunnable);
    hilo.start();
}

I put several gc, but they did not work, I read in SO that the gc does not help much, more or less I'm hitting 5000 rows with 25 columns and this is what happens when I hit it:

The heap never decreases, it keeps using up to 1gb and I need to leave all that memory in use, it's too late beating, I do not know what to do. If you have any reference or any way to do it, I would be very grateful, continuing in the profile, if I press the button to collect garbage in netbeans this immediately decreases the memory:

Here is an image of the Excel from which I extract the information to be copied, this file has 4500 rows and 33 columns.

Excel document example

And this is the jtable where I hit it.

PS: I'm new to java, all this I did reading and watching videos.

    
asked by Myth 03.10.2016 в 17:24
source

3 answers

1

Test with this code I have tried it up to 6000 records works fine although already when it exceeds that amount its performance goes down. I hope it serves you.

    Workbook wb;

    public String Importar(File archivo, JTable tablaD){
        String respuesta="No se pudo realizar la importación.";
        DefaultTableModel modeloT = new DefaultTableModel();
        tablaD.setModel(modeloT);
        tablaD.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        try {
            wb = WorkbookFactory.create(new FileInputStream(archivo));//CREAMOS UNA REPRESENTACIÓN DE HOJA EXCEL
            Sheet hoja = wb.getSheetAt(0);//SELECCIONAMOS LA HOJA DE LA POSICIÓN -> 0 DEL LIBRO
            Iterator filaIterator = hoja.rowIterator();
            int indiceFila=-1;
            while (filaIterator.hasNext()) {                
                indiceFila++;
                Row fila = (Row) filaIterator.next();
                Iterator columnaIterator = fila.cellIterator();
                Object[] listaColumna = new Object[1000];
                int indiceColumna=-1;
                while (columnaIterator.hasNext()) {                    
                    indiceColumna++;
                    Cell celda = (Cell) columnaIterator.next();
                    if(indiceFila==0){
                        modeloT.addColumn(celda.getStringCellValue());
                    }else{
                        if(celda!=null){
                            switch(celda.getCellType()){
                                case Cell.CELL_TYPE_NUMERIC:
                                    listaColumna[indiceColumna]= (int)Math.round(celda.getNumericCellValue());
                                    break;
                                case Cell.CELL_TYPE_STRING:
                                    listaColumna[indiceColumna]= celda.getStringCellValue();
                                    break;
                                case Cell.CELL_TYPE_BOOLEAN:
                                    listaColumna[indiceColumna]= celda.getBooleanCellValue();
                                    break;
                                default:
                                    listaColumna[indiceColumna]=celda.getDateCellValue();
                                    break;
                            }
                        }                        
                    }
                }
                if(indiceFila!=0)modeloT.addRow(listaColumna);
            }
            respuesta="Importación exitosa";
        } catch (IOException | InvalidFormatException | EncryptedDocumentException e) {
            System.err.println(e.getMessage());
        }
        return respuesta;
    }
    
answered by 30.10.2016 в 16:42
0

With more information (An example of the content of the excel, for example), we could give a more concrete answer. At the moment some tips for the use of RAM in Java (This applies to all Java, not just to Swing):

1) Do not instantiate objects within loops if you can avoid them, for example:

This code of yours:

for (int i = 0; i < size; i++) {
    StringTokenizer stk2 = new StringTokenizer(lista.get(0), "\t");
        for (int j = 0; stk2.hasMoreElements(); j++) {
            String value = stk2.nextToken();
            jTable1.setValueAt(value, i, j);
        }
        lista.remove(0);

        max++;
        System.out.println(max);
        jProgressBar1.setValue(max);
}

You create many StringTokenizer (stk2) and String (value), it would be better to create them once out and reuse the variables:

StringTokenizer stk2=null;
String value=null;
for (int i = 0; i < size; i++) {
    stk2 = new StringTokenizer(lista.get(0), "\t");
        for (int j = 0; stk2.hasMoreElements(); j++) {
            value = stk2.nextToken();
            jTable1.setValueAt(value, i, j);
        }
        lista.remove(0);

        max++;
        System.out.println(max);
        jProgressBar1.setValue(max);
}

2) You can "force" the Garbage collector of the JVM to eliminate the "garbage" (Variables that you have used and no longer use) if you limit the RAM that you give to the JVM. Example:

  • The command -Xmx1024m, would limit the size of the Heap to 1024MB, thus "forcing" the Grabage Collector to clean the "garbage" before reaching the limit. (1024 is just an example, you can use any value, but keep in mind that this can also make the program stop working if you do not have enough memory available.)

I give you a complete guide to these commands here: Heap Tuning Parameters .

(I'm sure you can optimize much more, these are general tips that can help something, but with more information about Excel, more we can help reduce the RAM problem) .

    
answered by 04.10.2016 в 11:26
0

I was able to find a solution after so long, I hope it will be helpful for someone, I have already done several tests and since the memory does not trigger in the same way, I leave the new code that I made:

   Clipboard cb;        
   StringSelection contents;
    String data = (String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor);
    contents = new StringSelection("Listo");
    cb = Toolkit.getDefaultToolkit().getSystemClipboard();
    cb.setContents(contents, contents);

I realized that when I called the method to get the clipboard of the system, the memory did not come up immediately if not 5 seconds after the process started, so what I did was change what was in the clipboard of the system leaving something smaller, and bualá the memory was not raised up to 1 Gb, I can copy 5000 excel records and everything perfect, I hope this is helpful to someone, thanks to all.

    
answered by 20.10.2016 в 18:34