首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java排列会导致堆空间错误

Java排列会导致堆空间错误
EN

Stack Overflow用户
提问于 2015-08-13 16:56:21
回答 2查看 652关注 0票数 0

我有一个程序,它生成数字组合的排列。排列具有给定的大小(在本例中为6)。我的问题是,我得到了一个java.lang.OutOfMemoryError: Java堆空间错误,它具有更大的数字组合。例如,如果我从18个数字中计算出置换,就会得到这样的异常:

代码语言:javascript
复制
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
at javax.swing.text.GapContent.allocateArray(Unknown Source)
at javax.swing.text.GapVector.resize(Unknown Source)
at javax.swing.text.GapVector.shiftEnd(Unknown Source)
at javax.swing.text.GapContent.shiftEnd(Unknown Source)
at javax.swing.text.GapVector.open(Unknown Source)
at javax.swing.text.GapVector.replace(Unknown Source)
at javax.swing.text.GapContent.insertString(Unknown Source)
at javax.swing.text.AbstractDocument.handleInsertString(Unknown Source)
at javax.swing.text.AbstractDocument.insertString(Unknown Source)
at javax.swing.text.PlainDocument.insertString(Unknown Source)
at javax.swing.JTextArea.append(Unknown Source)
at test.permute(test.java:48)
at test.permute(test.java:52)
at test.permute(test.java:52)
at test.permute(test.java:52)
at test.permute(test.java:52)
at test.permute(test.java:52)
at test.permute(test.java:52)
at test.actionPerformed(test.java:74)
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.plaf.basic.BasicButtonListener.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)

现在看来,这似乎是由打印出JTextArea中的排列引起的,因为如果您查看异常的第一行,就可以在javax.swing.text上看到错误。

下面是我使用的代码:

代码语言:javascript
复制
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;

public class test extends JFrame implements ActionListener {

    private JPanel panel;
    private JButton ok;
    private JTextArea text;
    private String str;
    private JScrollPane scroll;

    public test() { 
        panel = new JPanel();
        ok = new JButton("OK");
        ok.addActionListener(this);
        str = ("1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, ");
        text = new JTextArea(str, 16, 16);
        text.setEditable(true); 
        scroll = new JScrollPane(text);
        scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);


        panel.add(scroll);
        panel.add(ok);
        add(panel); 

        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void main(String[] args) {
        new test();
    }

    //-----------------------------------------------------------------------------------
    public void permute(java.util.List<Integer> intList, int k, int max) {
          if(k == max) {
            text.append(Arrays.toString(intList.subList(0, max).toArray()).replaceAll( "\\[|\\]", "") + ", \n");
          } else {
            for(int i = k; i < intList.size(); i++){
              java.util.Collections.swap(intList, i, k);
              permute(intList, k+1, max);
              java.util.Collections.swap(intList, k, i);
            }
          }
    }
    //-----------------------------------------------------------------------------------

    @Override
    public void actionPerformed(ActionEvent arg0) {
        String a = text.getText();  
        text.setText("");

        String[] zahlenstring = a.split(", ");
        int[] zahlenint = new int[zahlenstring.length];

        for(int i = 0; i < zahlenstring.length ;i++) {
            zahlenint[i] = Integer.parseInt(zahlenstring[i]); }

        ArrayList<Integer> intList = new ArrayList<Integer>();
        for (int i = 0; i < zahlenint.length; i++) {
            intList.add(zahlenint[i]); }

        permute(intList, 0, 6);    
    }
}

我寻找解决方案,但我主要找到了将ram添加到java或使用多线程的建议,这两者我都不想在这里使用。

现在我的问题是:我如何改进这段代码,这样它就不会再让我感到恶心了?这里还有什么需要改进的吗?

如果你还有问题,你可以在评论中问。提前谢谢。

EN

回答 2

Stack Overflow用户

发布于 2015-08-13 19:10:29

与其构建一个使用非常大(或不切实际)内存量的字符串,你需要处理每一个被确定的排列。

代码语言:javascript
复制
public static void permute(List<Integer> intList,  Consumer<List<Integer>> permutationConsumer) {
    permute(intList, 0, intList.size(), permutationConsumer);
}

public static void permute(List<Integer> intList, int k, int max, Consumer<List<Integer>> permutationConsumer) {
   if(k == max) {
        permutationConsumer.accept(intList.subList(0, max));
        return;
   }
   for(int i = k; i < intList.size(); i++) {
        Collections.swap(intList, i, k);
        permute(intList, k + 1, max, permutationConsumer);
        Collections.swap(intList, k, i);
   }
}

此解决方案将不再使用任何内存。

若要显示此结果,请执行以下操作

代码语言:javascript
复制
permute(intList, System.out::println);

这不会在显示前生成一个大字符串,因此不会耗尽内存。

票数 0
EN

Stack Overflow用户

发布于 2015-08-15 18:58:03

当您处理大量的元素时,最好提前计算它们将消耗多少内存。

你的排列会消耗掉

字节,假设每个组合消耗12个字节。因此,消耗的内存总量将在160 of左右。此内存量仅用于将组合存储为字符串。当您将它们添加到TextArea中时,至少需要加倍所需的内存量。

解决内存问题的最简单方法是,一旦计算出排列,就输出它。您可以将其写入控制台或文件。在这种情况下,您将不需要任何额外的内存。

但是,如果您的唯一选择是创建GUI应用程序,那么您可以执行以下操作。首先,您需要认识到至少(13366080 * k)字节用于排列字符串(其中k是每个置换字符串的大小),13366080 * 16字节用于存储字符串数组和一些额外的内存以使应用程序平稳运行(防止GC暂停)。如果我的计算是正确的,它将是大约500 my的堆内存。

接下来,不应该将字符串直接添加到TextArea中。相反,创建排列的ArrayList<String>,创建ScrollBar,用结果数组的大小初始化它。在ScrollBar的位置变化上,用ScrollBar位置的元素重新初始化TextArea (从滚动条的位置取少量的元素,并将它们作为行添加到TextArea中)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31994246

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档