Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将文本文件加载到列表时出现内存不足错误,即使我指定的xmx足够大_Java_List_Collections_Out Of Memory_Heap Memory - Fatal编程技术网

Java 将文本文件加载到列表时出现内存不足错误,即使我指定的xmx足够大

Java 将文本文件加载到列表时出现内存不足错误,即使我指定的xmx足够大,java,list,collections,out-of-memory,heap-memory,Java,List,Collections,Out Of Memory,Heap Memory,当我尝试在带有-Xms32m-Xmx128m的列表中加载39MB文本时,内存不足错误。所以我开始一点一点地增加Xmx,直到它成功加载,并发现我至少需要Xmx170m才能在内存中加载39MB的文件 我想知道,为什么我需要这么大的内存?我尝试使用UTF-8、UTF-16和UTF-32来计算列表中分配的内存量,但它们中似乎没有一个在出现内存不足异常时与Xmx匹配。那么,计算分配内存的正确方法是什么 有人能解释一下我遗漏了什么吗 下面是at-Xms32m-Xmx128m的输出和代码示例 Max memo

当我尝试在带有-Xms32m-Xmx128m的列表中加载39MB文本时,内存不足错误。所以我开始一点一点地增加Xmx,直到它成功加载,并发现我至少需要Xmx170m才能在内存中加载39MB的文件

我想知道,为什么我需要这么大的内存?我尝试使用UTF-8、UTF-16和UTF-32来计算列表中分配的内存量,但它们中似乎没有一个在出现内存不足异常时与Xmx匹配。那么,计算分配内存的正确方法是什么

有人能解释一下我遗漏了什么吗

下面是at-Xms32m-Xmx128m的输出和代码示例

Max memory 129 MB.
Total memory 32 MB.
Free memory 32 MB.
Input file size 39 MB.
Out Of Memory Error
List size in UFT-8 29 MB.
List size in UFT-16 58 MB.
List size in UFT-32 116 MB.
Free memory 4 MB.
End 

java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Unknown Source)
    at java.util.Arrays.copyOf(Unknown Source)
    at java.util.ArrayList.ensureCapacity(Unknown Source)
    at java.util.ArrayList.add(Unknown Source)
    at com.nrx.util.SortUtil.main(SortUtil.java:288)



public static void main(String[] args)
{
    System.out.println("Max memory "+Runtime.getRuntime().maxMemory()/1000 /1000+" MB.");
    System.out.println("Total memory "+Runtime.getRuntime().totalMemory()/1000 /1000+" MB.");
    System.out.println("Free memory "+Runtime.getRuntime().freeMemory()/1000 /1000+" MB.");

    long utf8 = 0;
    long utf16 = 0;
    long utf32 = 0;
    List<String> strList = new ArrayList<String>();
    try 
    {
        File inFile = new File("data/input38.log");
        System.out.println("Input file size "+inFile.length()/1000 /1000+" MB.");
        BufferedReader fileReader = new BufferedReader(new FileReader(inFile));
        String line = fileReader.readLine();
        while (line != null)
        {
            utf8 = utf8 + line.getBytes("UTF-8").length;
            utf16 = utf16 + line.getBytes("UTF-16").length;
            utf32 = utf32 + line.getBytes("UTF-32").length;

            StringTokenizer st = new StringTokenizer(line, " ");
            while(st.hasMoreTokens())
                strList.add(st.nextToken().trim());
            line = fileReader.readLine();
        }

    } 
    catch (OutOfMemoryError e) 
    {
        System.out.println("Out Of Memory Error ");
        System.out.println("List size in UFT-8 "+utf8/1000 /1000+" MB.");
        System.out.println("List size in UFT-16 "+utf16/1000 /1000+" MB.");
        System.out.println("List size in UFT-32 "+utf32/1000 /1000+" MB.");
        System.out.println("Free memory "+Runtime.getRuntime().freeMemory()/1000 /1000+" MB.");
        e.printStackTrace();
    }
    catch (FileNotFoundException e) 
    {
        e.printStackTrace();
    } 
    catch (IOException e) 
    {
        e.printStackTrace();
    }
    System.out.println("End ");
}
最大内存129 MB。
总内存32MB。
释放内存32MB。
输入文件大小39MB。
内存不足错误
列表大小以UFT-8 29 MB为单位。
列表大小以UFT-16 58 MB为单位。
列表大小以UFT-32 116 MB为单位。
释放内存4 MB。
终点
java.lang.OutOfMemoryError:java堆空间
位于java.util.Arrays.copyOf(未知源)
位于java.util.Arrays.copyOf(未知源)
位于java.util.ArrayList.ensureCapacity(未知源)
位于java.util.ArrayList.add(未知源)
位于com.nrx.util.SortUtil.main(SortUtil.java:288)
公共静态void main(字符串[]args)
{
System.out.println(“最大内存”+Runtime.getRuntime().maxMemory()/1000/1000+“MB”);
System.out.println(“总内存”+Runtime.getRuntime().totalMemory()/1000/1000+“MB”);
System.out.println(“空闲内存”+Runtime.getRuntime().freemory()/1000/1000+“MB”);
长utf8=0;
长utf16=0;
长utf32=0;
List strList=new ArrayList();
尝试
{
File inFile=新文件(“data/input38.log”);
System.out.println(“输入文件大小”+infle.length()/1000/1000+“MB”);
BufferedReader fileReader=new BufferedReader(new fileReader(infle));
String line=fileReader.readLine();
while(行!=null)
{
utf8=utf8+line.getBytes(“UTF-8”).length;
utf16=utf16+line.getBytes(“UTF-16”).length;
utf32=utf32+line.getBytes(“UTF-32”).length;
StringTokenizer st=新的StringTokenizer(行“”);
而(st.hasMoreTokens())
strList.add(st.nextToken().trim());
line=fileReader.readLine();
}
} 
捕获(OutOfMemory错误)
{
System.out.println(“内存不足错误”);
System.out.println(“列表大小单位为UFT-8”+utf8/1000/1000+“MB”);
System.out.println(“列表大小单位为UFT-16”+utf16/1000/1000+“MB”);
System.out.println(“列表大小单位为UFT-32”+utf32/1000/1000+“MB”);
System.out.println(“空闲内存”+Runtime.getRuntime().freemory()/1000/1000+“MB”);
e、 printStackTrace();
}
catch(filenotfounde异常)
{
e、 printStackTrace();
} 
捕获(IOE异常)
{
e、 printStackTrace();
}
系统输出打印项次(“结束”);
}

我认为这是因为您使用的是
ArrayList
。ArrayList是简单数组上的智能包装器。当列表增长时,ArrayList创建新数组并将旧内容复制到新数组。首先,它的效率极低。其次,它要求每次列表的大小为三倍:旧数组中有n个元素,新数组中有n*2个元素


因此,尝试使用
LinkedList
。我希望它对您有用。

您正在使用ArrayList。所以它是一个基于数组的列表。若不创建新的、更大的阵列,就无法更改阵列的大小。需要分配新的数组,并且需要将所有元素复制到更大的数组中(使用一些空白空间,以便添加一些元素时不会太重)。尝试将字符串[]表与指定数量的元素一起使用,以最小化其在内存中的大小并避免数组复制

我不确定,但我认为在Java中,字符串中的字符总是16位

Java中的字符串是共享和优化的,所以字符串大小的计算不是一个简单的操作

编辑:
我看到有人提到LinkedList,请注意,在该列表中,始终有其他指针变量也需要存储在内存中。

正如其他人在某些时候指出的,即使文件大小很小,也可能需要额外的内存来复制数组列表

为了获得更好的图片,您可以尝试找出文件大小每增加10 MB需要多少额外内存。一些内存量将是恒定的,并且无论文件大小如何都需要


其次,您还应该在执行完整GC之后测量内存。您可以使用JVisualVm查看占用内存的位置。

ArrayList的默认容量是10,之后它的容量增加了一倍,因此如果您有100000个元素,实际分配的容量可能是200000,这可能是此异常的原因。

-Xmx128m
(倾斜头)您确实实现了Java应用程序的默认内存。在1.6JRE中运行大约是256Meg,对吗?很好,Andrew。我甚至都没有注意到这个事实。@Alexer它以前不是在64兆左右吗?是的,我知道,我正在尝试不同的内存设置和文件大小,以找出文件大小和内存设置之间的关系。xmx256可以加载39MB的文件,但是当我尝试一个更大的文件时,我会遇到同样的错误,比如说100MB的LinkedList,我的最大内存是129MB。总内存32MB。释放内存32MB。输入文件大小39MB。内存不足错误列表大小(UFT-8 22 MB)。列表大小以UFT-16 44 MB为单位。列表大小以UFT-32 89 MB为单位。可用内存111MB。End java.lang.OutOfMemoryError:java.util.Arrays.copyOf(未知源)处的java堆空间位于java.lang.StringCodeing处的java.lang.StringCodeing.safeTrim(未知源)处的java.lang.StringCodeing处的java