2011-12-02 12 views
6

Tôi đã đi từ String test += str; trong đó test tăng trưởng theo cấp số nhân với hàng nghìn và hàng nghìn ký tự. Phải mất 45 phút để chạy, có lẽ từ việc tạo ra các chuỗi lớn và xóa rác. Tôi sau đó so le các đầu vào như thế này mà đưa nó đến 30 giây.StringBuilder hết lỗi bộ nhớ khi làm việc với các chuỗi lớn trong java

Điều này có vẻ như cách rẻ tiền để làm điều đó, nhưng nó hoạt động tốt:

if (secondDump.length() > 50) 
    { 
    intermedDump = intermedDump + secondDump; 
    secondDump = ""; 
    }  

    if (intermedDump.length() > 100) 
    { 
    thirdDump = thirdDump + intermedDump; 
    intermedDump = ""; 
    } 
    if (thirdDump.length() > 500) 
    { 
    fourthDump = fourthDump + thirdDump; 
    thirdDump = ""; 
    } 
    if (fourthDump.length() > 1000) 
    { 
    fifthDump = fifthDump + fourthDump; 
    fourthDump = ""; 
    } 
    //with just this and not sixth. Runtime>>>> : 77343 
    if (fifthDump.length() > 5000) 
    { 
    sixthDump = sixthDump + fifthDump; 
    fifthDump = ""; 
    } 
    //with just this. Runtime>>>> : 35903Runtime>>>> : 33780 
    if (sixthDump.length() > 10000) 
    { 
    fillerDump = fillerDump + sixthDump; 
    sixthDump = ""; 
    } 

sau đó tôi phát hiện ra rằng StringBuilder tồn tại, và tôi đã cố gắng để sử dụng nó từ đó, thay thế tất cả các hoạt động chuỗi với nó .

Vấn đề là, tôi tiếp tục nhận được java.lang.OutOfMemoryError với tràn bộ nhớ java. Tôi nghĩ rằng chuỗi chỉ là quá dài để lưu trữ trong bộ nhớ như là một đối tượng StringBuilder, bởi vì nó làm cho khoảng 1/50 của sự tiến bộ mà mã trước đây của tôi đã làm trước khi đâm với một lỗi bộ nhớ. Nó chỉ làm việc với có thể dưới một nghìn ký tự.

Tại sao chuỗi có thể giữ toàn bộ đầu ra và chuỗi này không thể đến gần? Ngoài ra, nếu tôi nối văn bản vào JTextPane, cần bao nhiêu bộ nhớ? Nếu tôi bỏ các nội dung StringBuilder sang JTextpane và tiếp tục thêm và xóa StringBuilder điều đó dường như không hoạt động.

Đây là mã hiện tại. Trang chỉ là một đối tượng được thông qua:

protected void concatPlates(page PageA) throws IOException 
{ 
    if (backend.isFirstPage == false) 
    { 
     frontend.fillOutputPane("\n         " + 
     "            \n", PageA); 
     frontend.fillOutputPane("         " + 
     "            \n", PageA); 
     frontend.fillOutputPane("         " + 
     "            \n", PageA); 
    } 
    for (int i = 0; i < PLATELEN-1; i++) 
    { 

     if (arrLeftCol[i].length() == 0) 
     { 
     ///////////////////////////////////////////////////////// 
     ///////////////////////////////////////////////////////// 
     frontend.fillOutputPane(arrLeftCol[i].append(
      arrRightCol[i])); 
     } 
    else 
    { 
     PageA.tempStrBuff = new StringBuilder(arrLeftCol[i].substring(0,40)); 
     frontend.fillOutputPane(PageA.tempStrBuff.append(arrRightCol[i])); 
    } 
    arrLeftCol[i].append(""); 
    arrRightCol[i].append(""); 

    backend.isFirstPage = false; 
    } 
} 


//this is the frontend class 
public static void fillOutputPane(String s, page PageA) 
{ 
    fillOutputPane(PageA.getStrBuf()); 
} 
public static void fillOutputPane(StringBuilder stringBuild) 
{ 
    try 
    { 
    str.append(stringBuild); 
    } 
    catch (java.lang.OutOfMemoryError e) 
    { 
    System.out.println((str.length() * 16) /8); 
    //System.out.println(str); 
    System.out.println("out of memory error"); 
    System.exit(0); 
    } 
} 

Dưới đây là lỗi:

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space 
at java.util.Arrays.copyOf(Unknown Source) 
at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source) 
at java.lang.AbstractStringBuilder.append(Unknown Source) 
at java.lang.StringBuilder.append(Unknown Source) 
at java.lang.StringBuilder.append(Unknown Source) 
at backend.fill(backend.java:603) 
at frontend$openL.actionPerformed(frontend.java:191) 
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source) 
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source) 
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source) 
at javax.swing.DefaultButtonModel.setPressed(Unknown Source) 
at javax.swing.AbstractButton.doClick(Unknown Source) 
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source) 
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source) 
at java.awt.Component.processMouseEvent(Unknown Source) 
at javax.swing.JComponent.processMouseEvent(Unknown Source) 
at java.awt.Component.processEvent(Unknown Source) 
at java.awt.Container.processEvent(Unknown Source) 
at java.awt.Component.dispatchEventImpl(Unknown Source) 
at java.awt.Container.dispatchEventImpl(Unknown Source) 
at java.awt.Component.dispatchEvent(Unknown Source) 
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) 
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) 
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) 
at java.awt.Container.dispatchEventImpl(Unknown Source) 
at java.awt.Window.dispatchEventImpl(Unknown Source) 
at java.awt.Component.dispatchEvent(Unknown Source) 
at java.awt.EventQueue.dispatchEventImpl(Unknown Source) 
at java.awt.EventQueue.access$000(Unknown Source) 
at java.awt.EventQueue$1.run(Unknown Source) 
at java.awt.EventQueue$1.run(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 

Tôi nghĩ rằng đây là những gì một vết đống là:

java.lang.Exception: Stack trace 
at java.lang.Thread.dumpStack(Unknown Source) 
at frontend.fillOutputPane(frontend.java:385) 
at page.concatPlates(page.java:105) 
at backend.setPlate(backend.java:77) 
at backend.fill(backend.java:257) 
at frontend$openL.actionPerformed(frontend.java:191) 
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source) 
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source) 
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source) 
at javax.swing.DefaultButtonModel.setPressed(Unknown Source) 
at javax.swing.AbstractButton.doClick(Unknown Source) 
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source) 
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source) 
at java.awt.Component.processMouseEvent(Unknown Source) 
at javax.swing.JComponent.processMouseEvent(Unknown Source) 
at java.awt.Component.processEvent(Unknown Source) 
at java.awt.Container.processEvent(Unknown Source) 
at java.awt.Component.dispatchEventImpl(Unknown Source) 
at java.awt.Container.dispatchEventImpl(Unknown Source) 
at java.awt.Component.dispatchEvent(Unknown Source) 
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) 
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) 
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) 
at java.awt.Container.dispatchEventImpl(Unknown Source) 
at java.awt.Window.dispatchEventImpl(Unknown Source) 
at java.awt.Component.dispatchEvent(Unknown Source) 
at java.awt.EventQueue.dispatchEventImpl(Unknown Source) 
at java.awt.EventQueue.access$000(Unknown Source) 
at java.awt.EventQueue$1.run(Unknown Source) 
at java.awt.EventQueue$1.run(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source) 
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source) 
at java.awt.EventQueue$2.run(Unknown Source) 
at java.awt.EventQueue$2.run(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source) 
at java.awt.EventQueue.dispatchEvent(Unknown Source) 
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)81240560 
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) 
at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
at java.awt.EventDispatchThread.run(Unknown Source) 
+1

Thông số VM của bạn là gì? Hãy thử tăng kích thước heap. – Viruzzo

+0

Bạn có thể vui lòng thêm mã nơi bạn đang sử dụng lớp StringBuilder. Lỗi có nhiều khả năng ở đó hơn. – JustinKSU

+0

Các chi tiết khác sẽ hữu ích. Tôi nghi ngờ chuỗi trong bộ nhớ là làm cho bạn hết bộ nhớ. Bạn có stacktrace? –

Trả lời

5

Rõ ràng ứng dụng của bạn doen't có đủ bộ nhớ để hoàn thành hoạt động. Vì vậy, bạn cần phải chỉ định cờ bộ nhớ cho máy ảo của bạn. Bạn có thể thử như sau:

java -Xms256m -Xmx512m YourApp 

đâu:

  • XMS minimun bộ nhớ được phân bổ bởi chương trình của bạn lúc khởi động (trong ví dụ 256 MB)
  • Xmx nhớ maximun giao chương trình của bạn nếu nó cần nhiều hơn (trong ví dụ 512 MB)
+1

Đó là một giải pháp sửa lỗi nhanh không thực sự mở rộng hoặc giải thích cách sử dụng String và StringBuilder thực sự ảnh hưởng đến mức tiêu thụ bộ nhớ. –

+2

Đó không được coi là một sửa chữa nhanh - càng có nhiều dữ liệu bạn muốn giữ trong bộ nhớ càng nhiều bộ nhớ bạn cần. – Puce

+0

Althoug StringBuilder có thể cần bộ nhớ nhiều hơn một chút so với một đối tượng String duy nhất vì nó giữ mở một số khe miễn phí cho dữ liệu mới. – Puce

3

Một trong những điều có thể xảy ra là trong Java, java.lang.String được điều trị đặc biệt. Các chuỗi là bất biến, và do đó JVM đặt mỗi đối tượng String trong một nhóm. Vai trò của nhóm này, trong số những người khác là một thực tế được sử dụng như một loại "bộ nhớ cache", nơi bạn tạo nhiều trường hợp chuỗi có "văn bản" thực tế giá trị giống hệt nhau, cùng một cá thể sẽ được tái sử dụng từ nhóm. Bằng cách này tạo ra những gì có vẻ là một số lượng lớn các thể hiện đối tượng String với cùng một văn bản bên trong sẽ infact hoàn nguyên về việc có rất ít trường hợp String thực tế trong bộ nhớ. Mặt khác, nếu bạn sử dụng cùng một văn bản để khởi tạo nhiều trường hợp StringBuilder, những thực tế đó sẽ là các cá thể riêng biệt (chứa cùng một văn bản), và do đó chiếm nhiều bộ nhớ hơn.

Mặt khác, ghép các chuỗi (chẳng hạn như String c = "a"+"b";) trong thực tế sẽ tạo ra nhiều trường hợp đối tượng hơn nếu bạn làm điều đó với StribgBuilder (chẳng hạn như new StringBuilder("a").append("b");).

+0

Tôi hiểu. Vì vậy, bạn có nghĩ rằng đây là những gì có thể gây ra lỗi bộ nhớ? Tôi không nghĩ rằng một đối tượng StringBuilder duy nhất có dưới một nghìn ký tự sẽ sử dụng nhiều bộ nhớ đó. – montag

+0

Tôi chỉ nhận ra rằng nó có thể là hơn một nghìn ký tự. – montag

+0

Bạn có thể gỡ rối nó với Eclipse để tìm ra chuỗi dài bao nhiêu? – davidfrancis