JDK-5089193 : JTextArea.setText() wastes megabytes of memory!
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2004-08-19
  • Updated: 2004-08-19
  • Resolved: 2004-08-19
Related Reports
Duplicate :  
Relates :  
Description

Name: js151677			Date: 08/19/2004


FULL PRODUCT VERSION :
java version "1.4.2_05"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_05-b04)
Java HotSpot(TM) Client VM (build 1.4.2_05-b04, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows 2000 [Version 5.00.2195]

A DESCRIPTION OF THE PROBLEM :
When displaying a bigger text in a JTextArea, the amount of used memory suddenly jumps up after calling setText().

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Try to load e.g. a 10MB big text file (usual size of our log files) with the attached code using the standard java.exe. Inspect the System.out and especially the memory usage.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Output of "used mem after setText()" should not or just slightly be bigger that output of "used mem before setText(): "
ACTUAL -
Output of "used mem before setText(): " is 10 MB, after adding the StringBuffer (7 MB), "used mem after setText(): " is suddenly 65 MB!
If you started java.exe without increasing memory (i.e. without -Xmx parameter), you probably get an OutOfMemoryError.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
        /**
         * Get text content of a file..
         *
         * @param file File to read text content from.
         * @param textArea JTextArea to set content of <i>file</i> with.
         * @throws IOException
         */
        private void readText(File file, JTextArea textArea) throws IOException {
            if (file != null && textArea != null) {
                BufferedReader br = null;
                ProgressMonitor pm = null;
                try {
                    textArea.setText("");
                    FileInputStream fis = new FileInputStream(file);
                    ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(parent , "Reading " + file.getName(), fis);
                    pm = pmis.getProgressMonitor();
                    pm.setProgress(0);
                    pm.setMillisToDecideToPopup(0);
                    pm.setMillisToPopup(3000);
                    InputStreamReader isr = new InputStreamReader(pmis);
                    br = new BufferedReader(isr);

                    String line = null;
                    boolean first = true;

                    StringBuffer sb = new StringBuffer((int) file.length() + 1000);
                    while ((line = br.readLine()) != null) {
                        if (first) {
                            first = false;
                        } else {
                            sb.append("\n");
                        }
                        sb.append(line);
                    }
System.out.println("sb len: "+sb.length()); //7 MB
System.out.println("used mem before setText(): "+(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())); //10 MB
                    textArea.setText(sb.toString());
System.out.println("used mem after setText(): "+(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())); //65 MB!!!

                    textArea.setCaretPosition(textArea.getDocument().getLength()); //scroll down
                } catch (InterruptedIOException iioe) {
                    /* user canceled loading */
                    if (pm != null && pm.isCanceled()) {
                        pm.close();
                        Toolkit.getDefaultToolkit().beep();
                        System.err.println("Canceled by user.");
                    }
                } catch (OutOfMemoryError oome) {
                    System.err.println("ERROR Out of memory: "+oome);
                } finally {
                    if (br != null) {
                        br.close();
                    }
                }
            }//else: file unavailable
        }//readText()
---------- END SOURCE ----------
(Incident Review ID: 297578) 
======================================================================

Comments
EVALUATION I am closing this bug a dup for 4203912 [JTextArea uses too much memory (if large byte array] Loading huge documents into JTextArea always has some overhead. Each character takes two bites. Each line takes about 100 bites in addition to the content (for plain document). 10mb text file is about 130000 lines (80 character per line) Total memory usage going to be : 10mb * 2 + 130000 * 100 = about 35 mb Before 4203912 was fixed total memory used could be twice this number. One could always implement a better handling for huge documents. ###@###.### 2004-08-19
19-08-2004