Java 堆过载JVM
编辑***:就目前情况而言,我有一个程序不知何故陷入了无限循环,但我不确定是什么导致了它。我的程序从一个文本文件中读入数据,并基本上“切断”每行上的第一部分数据,直到第一次出现“,”字符,然后读取随后的每个字符串(在一般情况下以“”结尾),直到下一个“,”(特殊情况下,表示以下数据也是垃圾数据)。从那里,它跳到下一行并重复。几周前,我的程序运行良好,但我对它进行了修补,现在它正式被破坏了。在这个编辑下面是我遇到的一些其他错误(我可能仍然需要解决),但目前,我正在某个地方被这个循环杀死。诚然,我有一个诀窍,就是使用嵌套for循环,使用时髦的迭代器和更新,但我就是不能破解这个。下面是代码,并有一些解释。这整个代码段只是被抛出到某个采用字符串“synset”的任意类的构造函数中,并在我的main中创建了一个实例。我已经尽可能地对其余部分进行了评论:Java 堆过载JVM,java,overflow,heap,inputstream,Java,Overflow,Heap,Inputstream,编辑***:就目前情况而言,我有一个程序不知何故陷入了无限循环,但我不确定是什么导致了它。我的程序从一个文本文件中读入数据,并基本上“切断”每行上的第一部分数据,直到第一次出现“,”字符,然后读取随后的每个字符串(在一般情况下以“”结尾),直到下一个“,”(特殊情况下,表示以下数据也是垃圾数据)。从那里,它跳到下一行并重复。几周前,我的程序运行良好,但我对它进行了修补,现在它正式被破坏了。在这个编辑下面是我遇到的一些其他错误(我可能仍然需要解决),但目前,我正在某个地方被这个循环杀死。诚然,我有
In in = new In(synsets); // Custom input stream class, courtesy
// of Princeton U
Out fout = new Out("log.txt"); // ostream analogue
int linecount=0; // Marker used to keep track of line # in input file
int nouncount=0; // Marker for keeping track of the number of
// "important" data items
// Data comes in the format:
// "junk,important important important,junk
// junk,important,junk
// junk,important important,junk" etc.
{
int i=0;
for ( String str=in.readLine();str!=null;str=in.readLine() )
{
i=0; // reset iterator for a new line
for ( char next=str.charAt(i); next!=',';next=str.charAt(i) )
i++; // This FOR loop cuts out the junk at the start of
// a line
i++; // increment to after first comma
for ( char next=str.charAt(i);next!=',';next=str.charAt(i))
{
for (; next!=',' && next!=' ' ;next=str.charAt(i))
{
i++;
fout.print(next);
// count the "nouns" (important data) on a line
}
nouncount++;
// count the last noun on line, and subsequently fall
// through loops to skip the rest of the junk at the
// current line
fout.print('\n');
}
}
fout.print(nouncount);
in.close();
我的输出文件很好,直到输入的第18行,在这一点上它才开始打印新行字符(就像它在循环中被捕获,附加它们,但不能进入下一个循环)。下面是有问题的输入行。它的读数是24克拉黄金,但由于某种原因,它并没有变成纯金。有什么想法吗?谢谢你,亚尔
“17,24克拉黄金纯金,100%黄金18,24/7,正常运行时间为每天24小时,每周7天” 编辑*:我正在编写一个程序,从文本文件中读入一些数据,并收到一条新的(对我来说)错误消息,表明堆空间已用完。我试图修补这个bug,但只成功地消除了错误消息。我从中读取的文本文件大约有90K行,但我的程序在第18行抛出了消息。我的修补确实揭示了一些事情,特别是,我的程序至少能够对整个文件进行一些处理,而且这个问题可能涉及一些数据损坏。我推断这是因为我使用的数组索引“j”触发了IndexOutOfBoundsException。问题是,j每次递增时只按1缩放,不知何故,它超出了比数组边界高出150000的范围。因此,我假设“j”以某种方式被数据填充(可能是因为堆栈被覆盖到堆中?),这与“j”或所讨论的数组无关。下面是我的原始帖子,虽然我承认我很累,所以它可能没有太多意义。谢谢你,亚尔!:) 编辑**:我检查了NonuCount,它是399850,所以我没有遇到数据损坏,正如我所怀疑的那样。我的一个循环就是无限执行。如果我能纠正这个问题,我会设法找出哪一个,然后发回。我至少会回来整理一下这篇文章,以便将来有需要的人阅读 我正在写一个程序,读取一个文本文件,它必须进行一些计数(文件中的数据以非常语法的方式进行划分),但我的代码不能走得很远。虽然该文件相当丰富(大约90K行),但在堆溢出之前,我的代码只有17行 在某些背景下,“In”类只是一个专门的输入流,而真正让我头疼的并不是第一个FOR循环,在这里我计算行数(代码很好地执行这一部分,每行单独读取一次)。更确切地说,这是第二部分,但我不明白,因为我没有在该部分中使用任何额外的堆空间(我想?)。我以前把这些块放在一起,一行一行地完成主要功能,但是程序还是会停在第17行。我尝试在DrJava中分配高达GB的堆空间,但没有成功。在下半部分中是否有可以留出额外堆空间的部分
In in = new In(synsets);
StringBuilder nounData = new StringBuilder();
int linecount=0;
int nouncount=0;
{
String str;
int i=0;
char next='\0';
for ( str=in.readLine();str!=null;str=in.readLine() )
{
linecount++;
}
in.close();
in = new In(synsets);
for ( str=in.readLine();str!=null;str=in.readLine() )
{
i=0;
// The first portion of each line is "trash" until the first comma
for ( next=str.charAt(i) ; next!=',' ; next=str.charAt(++i) ){}
i++;
// This actually reads/processes the data until the next comma, then
// jumps to the next line. "What" i need done is really secondary, I
// just need to figure out what is eating so much space so I can
// trim it
for ( next=str.charAt(i);next!=',';next=str.charAt(i))
for (;next!=','&&next!=' ';next=str.charAt(++i))
nouncount++;
}
}
下面是更新后的代码,我试图从Dr Java重新创建Heap消息。虽然我无法做到这一点,但我确实收到了一条有趣的错误消息(当然是在第18行),关于数组越界。尽管如此,我仍然感到困惑,因为我不知道当变量被击中时,它怎么会超过17
代码如下:
In in = new In(synsets);
StringBuilder nounData = new StringBuilder();
int linecount=0;
int nouncount=0;
{
int i=0;
for ( String str=in.readLine();str!=null;str=in.readLine() )
{
i=0;
for ( char next=str.charAt(i);next!=',';next=str.charAt(i))
for (;next!=','&&next!=' ';next=str.charAt(++i))
nouncount++;
}
in.close();
in=new In(synsets);
String[] nouns = new String[nouncount];
int j=0;
for ( String str=in.readLine();str!=null;str=in.readLine() )
{
linecount++;
i=0;
for ( char next=str.charAt(i) ; next!=',' ; next=str.charAt(++i) ){}
i++;
for ( char next=str.charAt(i);next!=',';next=str.charAt(i))
{
for (;next!=','&&next!=' ';next=str.charAt(++i))
nounData.append(next);
nouns[j++]=nounData.toString();
nounData.delete(0,nounData.capacity()-1);
}
System.out.println("Current line count is: " + linecount);
}
}
in.close();
System.out.println("line count = "+linecount);
System.out.println("noun count = "+nouncount);
String[] nouns = new String[nouncount];
下面是错误消息:
Current line count is: 1
Current line count is: 2
Current line count is: 3
Current line count is: 4
Current line count is: 5
Current line count is: 6
Current line count is: 7
Current line count is: 8
Current line count is: 9
Current line count is: 10
Current line count is: 11
Current line count is: 12
Current line count is: 13
Current line count is: 14
Current line count is: 15
Current line count is: 16
Current line count is: 17
java.lang.ArrayIndexOutOfBoundsException: 399850
at WordNet.<init>(WordNet.java:39)
at WordNet.main(WordNet.java:212)
文件中的字符数一直到第18行是917,第19行是966,所以我不认为我错放了那一行
编辑:此外,我做了一个测试,文件中只有大约147K个“名词”,所以我猜“j”不知怎么被破坏了,因为它必须从0到147K之间的某个值“跳”到399K+。不幸的是,这已经过了我的就寝时间,所以我今晚无法继续更新,但请随意发布任何想法,明天早上我会通过电子邮件检查:)谢谢大家 为测试条件更改所有的
next!=','
到
应该是哪一个
for (;next!=','&&next!=' '&&i+1<str.length();next=str.charAt(++i))
您可以通过words.length
获得字数。要获取行计数,请在调用readLine()
like时增加一个计数器
in = new In(synsets);
// for ( str=in.readLine();str!=null;str=in.readLine() )
while ((str = in.readLine()) != null) {
linecount++;
String[] words = str.split(",\\s+);
nouncount += words.length;
}
不存在“堆溢出”这样的情况,而且您似乎没有在内存中保留任何对象,因此不应该使用太多的堆。很可能您没有正确读取错误消息。你能把它贴在这里让我们看看是什么吗。我实际上没有任何错误消息,但是当我的代码被压缩时,我得到了堆通知。相反,如果我在第二行中为chunk添加某种print命令,它将无限期地停留在第18行,在那里我之前得到了heap消息。我会看看我是否不能重新创建消息,但是,@user3118524是in=newin(synset)在.close()中之后的code>行
?您应该能够读取错误消息
for (;next!=','&&next!=' ';next=str.charAt(++i))
for (;next!=','&&next!=' '&&i+1<str.length();next=str.charAt(++i))
String[] words = str.split(",\\s+);
in = new In(synsets);
// for ( str=in.readLine();str!=null;str=in.readLine() )
while ((str = in.readLine()) != null) {
linecount++;
String[] words = str.split(",\\s+);
nouncount += words.length;
}