Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.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 CharBuffer位于由TeBuffer映射的内存之上,而不使用大量堆空间_Java_Regex_Memory_Netbeans - Fatal编程技术网

Java CharBuffer位于由TeBuffer映射的内存之上,而不使用大量堆空间

Java CharBuffer位于由TeBuffer映射的内存之上,而不使用大量堆空间,java,regex,memory,netbeans,Java,Regex,Memory,Netbeans,我正在编写一个java代码,在一个大的txt文件(6-8Gb)中搜索电子邮件地址和密码。我已经编写了代码,它使用200Mb的txt文件并给出了输出。但是当我输入一个500Mb的文件时,它会显示以下错误 Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.nio.HeapCharBuffer.<init>(HeapCharBuffer.java:57) at java.nio.Ch

我正在编写一个java代码,在一个大的txt文件(6-8Gb)中搜索电子邮件地址和密码。我已经编写了代码,它使用200Mb的txt文件并给出了输出。但是当我输入一个500Mb的文件时,它会显示以下错误

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.nio.HeapCharBuffer.<init>(HeapCharBuffer.java:57)
at java.nio.CharBuffer.allocate(CharBuffer.java:331)
at java.nio.charset.CharsetDecoder.decode(CharsetDecoder.java:792)
at regular.expression_fyp.RegularExpression_fyp.main(RegularExpression_fyp.java:56)
Java Result: 1

您是否尝试过减小文件缓冲区大小?也许你应该做一个优化的方法来实现这一点,看起来你的缓冲区中满是6Gb的文件,这就是你的应用程序被破坏的原因

您可以尝试增加jvm的堆大小。您可以使用
java-Xms[初始堆大小]-Xmx[最大堆大小]


检查答案,看看是否有帮助。

问题在于CharBuffer正在转换字节,从而将文件放入堆中。一个更有效的解决方案是为ByteBuffer编写一个包装器,它允许您直接创建内存映射文件

您可以创建一个CharSquence,它包装ByteBuffer来解析整个映射,而无需将其放入堆中

import java.nio.ByteBuffer;

/**
 * Assumes ISO-8859-1 character encoding
 */
public class BufferCharSequence implements CharSequence {
    final ByteBuffer bb;

    public BufferCharSequence(ByteBuffer bb) {
        this.bb = bb;
    }

    @Override
    public int length() {
        return bb.limit();
    }

    @Override
    public char charAt(int index) {
        return (char) (bb.get(index) & 0xFF);
    }

    @Override
    public CharSequence subSequence(int start, int end) {
        bb.limit(start + end);
        bb.position(start);
        return new BufferCharSequence(bb.slice());
    }
}

注意:正如已经推荐的那样,这将使用,克服此问题的一个好方法是以较小的批从文件加载数据。但还有另一种方法,您应该了解Java程序是如何分配内存的:

JVM在启动期间获得有限的内存。为了使事情变得更复杂,可以调整JVM内存中的几个不同区域,但正如您的“java.lang.OutOfMemoryError:java heap space”消息所示,我们对一个名为heap的特定区域感兴趣

您可以自己指定堆的大小,类似于下面的示例,向Java程序授予1G内存:

java -Xmx1024m com.mycompany.MyApplication
如果您的JVM已经在运行,您可以查看指定参数的值,例如,通过检查列出启动参数的jps命令的输出,您可以看到熟悉的-Xmx再次将允许的最大堆的值指定为1GB:

my-machine:demo me$ jps -lvm
6116 com.mycompany.MyClass -Xmx1024m
如果您自己没有指定,将使用特定于平台的默认值,您可以通过使用-XX:+PrintFlagsFinal属性列出java的输出来检查该值,该属性以字节为单位列出输出,但同样,输出列出的堆大小正好等于1GB或1073741824字节:

my-machine:demo me$ java -XX:+PrintFlagsFinal |grep MaxHeapSize
uintx MaxHeapSize                              := 1073741824      {product} 

因此,尽管批量加载可以而且会有所帮助,但有时只需投入更多的资源就可以更容易地解决问题。因此,当面临下一个“java.lang.OutOfMemoryError:java堆空间”错误时,您有时可以通过增加JVM的可用资源来绕过它。

感谢大家的贡献!因为我在使用netbeans,所以我找到了另一种方法(今天)。根据我在项目属性和运行中的描述,我在vm选项中添加了-Xmx1000m。所以现在我的程序运行良好。但是我想知道这是否会在将来给我带来任何错误,因为我想让这个程序可以执行。因此,这也应该在其他windows操作系统中运行。这个更改将来会给我带来什么问题吗?

你不能先把文件分成几行吗?你不能一次将文件全部加载到内存中。内存映射文件可能是一种解决方案。或者其他一些方法,可以在文件仅部分传输到内存时读取该文件。这可能会有所帮助:@Fildor:这个问题中的
ByteBuffer
是一个内存映射文件。是转换成一个
CharBuffer
的过程让他大吃一惊。使用数据库。这就是他们的目的。非常感谢你的帮助。我很感激。如何更改编码,例如UTF-8?@PeterKeller更复杂,因为您需要处理多字节字符,并且根据您的使用情况,如果您想要随机访问,您可能需要构建有效的树结构。您可以使用存储每N个字符(例如每256个字符)偏移量的数组,并在这些字符内进行线性扫描。显然,您希望索引脱离堆,使用的内存比字符串本身少。谢谢您的回答!我真的很感激你的帮助!现在我在我的项目中添加了-Xmx1000m。所以它工作得很好。我想这就是你的答案?再次感谢你!
my-machine:demo me$ java -XX:+PrintFlagsFinal |grep MaxHeapSize
uintx MaxHeapSize                              := 1073741824      {product}