今天无聊在研究excel读写,发现个问题,在for循环(高亮)的22753时,正常读写excel,在超过22753时,不是超很多的情况下,会报,Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at jxl.read.biff.File.next(File.java:181)
at jxl.read.biff.SheetReader.read(SheetReader.java:373)
at jxl.read.biff.SheetImpl.readSheet(SheetImpl.java:686)
at jxl.read.biff.WorkbookParser.getSheet(WorkbookParser.java:252)
at jxl.read.biff.WorkbookParser.getSheet(WorkbookParser.java:285)
at com.excel.ReadExcel.main(ReadExcel.java:83)
错误,
在23000时,会报
Exception in thread "main" java.lang.NullPointerException
at com.excel.ReadExcel.main(ReadExcel.java:127)错误,
求教,个人认为是何java虚拟机有关!Excel版本是2003package com.excel;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;import jxl.*;
import jxl.format.CellFormat;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.WritableCell;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;
public class ReadExcel {
static Workbook workbook;
static WritableWorkbook workbookWrite;
static Workbook readOutPutXLS;
public static void main(String [] args) {
try {
//read data from excel
workbook = Workbook.getWorkbook(new File("c:\\excel.xls"));
Sheet sheet = workbook.getSheet(0);
Cell value1 = sheet.getCell(0,0);
Cell value2 = sheet.getCell(1,0);
Cell value3 = sheet.getCell(2,0);
Cell value4 = sheet.getCell(3,0);
String str1 = value1.getContents();
String str2 = value2.getContents();
String str3 = value3.getContents();
String str4 = value4.getContents();
String sheetName = sheet.getName();
System.out.print("Read from " + sheetName + "  ");
System.out.println("Result is " + str1 + " : "+ str2 + " : "+ str3 + " : " + str4);
//write data into excel
//workbookWrite = Workbook.createWorkbook(new File("c:\\test.xls")); 
workbookWrite = Workbook.createWorkbook(new File("c:\\output.xls"), workbook);  
//WritableSheet sheet2 = workbookWrite.getSheet(1);
int count = 0;
Date startTime = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
String strStart = sdf.format(startTime);
System.out.println(strStart);


for(int i = 5; i < 22753; i++) {
WritableSheet  writeSheet = workbookWrite.createSheet("test" + i, i);
count++;
}
System.out.println("created " + count + " Sheets");
WritableSheet  writeSheet = workbookWrite.createSheet("test4", 4);
WritableCell cell = writeSheet.getWritableCell(1,2);
int cellCol = cell.getColumn();
int cellRow = cell.getRow();
System.out.println("cell's (Column,Row) is " + "(" +cellCol + ", " + cellRow + ")");

for(int i = 0; i < 100; i++) {
Label label4 = new Label(0, i, String.valueOf(i+1));
writeSheet.addCell(label4);
}
System.out.println("step2");
for(int i = 1; i < 10; i++) {
Label label4 = new Label(i, 3, String.valueOf(i+1));
writeSheet.addCell(label4);
}
System.out.println("step3");
Label label = new Label(5, 6, "たべる");
writeSheet.addCell(label);
System.out.println("before step4");

workbookWrite.write();
workbookWrite.close();

System.out.println("step4");
readOutPutXLS = Workbook.getWorkbook(new File("c:\\output.xls"));
Sheet readOutPutXLSSheet = readOutPutXLS.getSheet(writeSheet.getName());
System.out.println(writeSheet.getRows());
int sum = 0; 

for(int i = 0; i < writeSheet.getRows(); i++) {
Cell readOutPutXLSCell = readOutPutXLSSheet.getCell(0, i);
String str = readOutPutXLSCell.getContents();
int strToInt = Integer.parseInt(str);
sum += strToInt;
}
System.out.println("sum is " + sum);
Cell [] c = readOutPutXLSSheet.getRow(3);
for(int i =0; i < c.length;i++) {
if(i == c.length -1 ) {
System.out.print(c[i].getContents());
}
else
System.out.print(c[i].getContents() + " : ");  
}

Date endTime = new Date();
SimpleDateFormat sdfend = new SimpleDateFormat("HH:mm:ss");
String strEnd = sdfend.format(endTime);
System.out.println(strEnd);


} catch (BiffException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RowsExceededException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (WriteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}  finally {
workbook.close();

System.out.println("\nexcelReader is closed!");
readOutPutXLS.close();
System.out.println("excelReader readOutPutXLS is closed!"); }

}
}

解决方案 »

  1.   

    设置下你的java虚拟机内存大小 具体怎么设置 百度一下
      

  2.   

    推荐一个工具:JVM堆图形分析工具 - HeapAnalyzer
      

  3.   

    额,设置一下jvm的内存分配……
      

  4.   

    heap是堆 stack是栈
    估计就是你的堆空间值太小了  或者你读取运行的时候数据冗余太大了
      

  5.   

    优化代码 或者 把 JVM  mms mmx 设大一点,,
    我今天也碰到过几次 ,PermGem out of memory,,  把参数MaxPermSize设大一点,解决的 :)  
      

  6.   

    百度 google里很多这个的答案。----------太懒了!
    3种可能:
    有三种可能导致OutOfMemoryError。首先是,此JVM有真实的内存泄漏,导致此JVM堆在内部实现时产生了一个Bug。这极不可靠。所有 JVM都经过充分的测试,并且,如果有人发现这种bug,它将绝对是最高的优先级。因此你可以非常宽心地排除这种可能性。  第二种可能的OutOfMemoryError原因只不过是,你没有为你的应用程序运行时给予足够多的可用内存。这种情况,有两种可能的方案,或者增加 JVM堆可用大小,或者减少你的应用程序所需的内存总量。提高JVM可用堆大小可以简单的使用JVM的 -Xmx 参数。假如你将此参数设置尽可能的大(可用内存极限不要超过系统物理内存,否则你的应用程序将分页并暂停),仍然有以上所提到的内存问题,那么,你需要减少你的应用程序所可能用到内存总量。减少应用程序内存可能是简单的,你可能允许一些集合过大,例如使用了许多大的缓冲区。或者它过于复杂,要求你重新实现一些类,乃至重新设计应用程序。  读者 Jams Stauffer 指出有些JVM(例如 sun的 JVMs),还有一个“Perm”参数用来处理JVM结构与类对象。如果你正在使用一个数量非常巨大的类集,它有可能运行在"Perm"空间之外,然后你需要增加此空间的大小,例如,sun的JVM使用 -XX:PermSize 与 -XX:MaxPermSize 选项。  第三种导致OutOfMemoryError最为常见,无心的对象引用保持。你没有明确无误的释放对象,以致于你的堆增长再增长,直到你没有额外的空间。  处理OutOfMemoryError:
    是JVM内部的BUG?不太可能。如果是,这是优先级最高的BUG(为什么还没有人发现它,而你碰到了?)。  没有足够的内存分配给实际运行的应用程序?两种选择:使用-Xmx参数增加堆的最大使用内存(或者使用-XX:MaxPermSize参数增加Perm空间大小); 或者使用更小的集合/缓冲区/表空间/对象.....,以减少所需要的内存总量,也就是说,可以调整对象大小,重新设计与重新实现你的应用程序。无心的对象引用保持?找到保持这些无意引用的源对象,改变它并释放这些对象。在IBM开发者社区的文章纲要式的揭示了这样一个通用的处理过程。这个过程主要是等到应用程序到达恒定状态--你将期望最多的新创建的对象是临时对象,并且可以被垃圾收集器收集。这常常是在应用程序所有的初始化工作完成之后。强迫垃圾收集,获得一个堆的对象快照。
    做任何工作可能正在导到无意的对象引用保持。
    强迫另一次垃圾收集并获得第二次堆的对象快照。
    比较这两个快照,观察从第一个快照到第二个快照哪些对象在数量上有所增加。因为你在快照之前强迫垃圾收集,剩下的将是所有被应用程序引用的对象,比较两个快照将准确的标识那些新创建的、保留在应用程序里的对象。
    根据你对应用程序的认识,决定两个快照比较中,哪些对象正在无意的保持对象引用。
    跟踪前导引用,找到哪些对象正在引用这些无意的保持对象,直到你找到导致此问题的源对象启动虚拟机的时候,加上一个参数:-Xms800m -Xmx800m就好了
    -Xms <size>
    设置JVM初始化堆内存大小-Xmx <size>
    设置JVM最大的堆内存大小如果是应用程序,则:java -Xms800m -Xmx800m 你的类名
    如果是tomcat之类的web服务器,在这个服务器的启动文件后面加上这个参数即可。
      

  7.   

    这个错误的意思是指,JVM 的垃圾回收器已经没有可回收的垃圾对象了,在内存中的对象全都不是垃圾对象,也就是说全都被引用着,这样导致 JVM 用于存放对象的空间耗尽,无法为新对象再开僻新的内存。解决方法:
    1,避免将大量的数据往集合面里塞
    2,在 java 命令中加上 -Xmx 参数,扩大 JVM 内存,默认值我记得好像是 64m
      

  8.   

    用的是eclipse吧,
    把eclipse.ini里面的配置改下就行了,
    这是我的
    -showsplash
    org.eclipse.platform
    --launcher.XXMaxPermSize
    256M
    -framework
    plugins\org.eclipse.osgi_3.4.3.R34x_v20081215-1030.jar
    -vmargs
    -Dosgi.requiredJavaVersion=1.5
    -Xms40m
    -Xmx512m
      

  9.   

    堆栈溢出   一般就是你不太了解各种类型的范围除的错误     你也可能在数组出现数组溢出 所以建议你去看看java大学使用教程  看看char string int 他们的范围都是多少