I am writing some code to parse a very large flat text file into objects which are persisted to a database. This is working on sections of the file (i.e. if I 'top' the first 2000 lines), but I am running into a java.lang.OutOfMemoryError: Java heap space
error when I try and process the full file.
I am using a BufferedReader to read the file line by line, and I was under the impression that this negates the requirement to load the entire text file into memory. Hopefully my code is fairly self-explanatory. I have run my code through the Eclipse Memory Analyser, which informs me that:
The thread java.lang.Thread @ 0x27ee0478 main keeps local variables with total size 69,668,888 (98.76%) bytes.
The memory is accumulated in one instance of "char[]" loaded by "<system class loader>"**
Helpful comments greatly appreciated!
Jonathan
public ArrayList<Statement> parseGMIFile(String filePath)
throws IOException {
ArrayList<Statement> statements = new ArrayList<Statement>();
// Statement Properties
String sAccount = "";
String sOffice = "";
String sFirm = "";
String sDate1 = "";
String sDate2 = "";
Date date = new Date();
StringBuffer sData = new StringBuffer();
BufferedReader in = new BufferedReader(new FileReader(filePath));
String line;
String prevCode = "";
int lineCounter = 1;
int globalLineCounter = 1;
while ((line = in.readLine()) != null) {
// We extract the GMI code from the end of the first line
String newCode = line.substring(GMICODE_START_POS).trim();
// Extract date
if (newCode.equals(prevCode)) {
if (lineCounter == DATE_LINE) {
sDate1 = line.substring(DATE_START_POS, DATE_END_POS).trim();}
if (lineCounter == DATE_LINE2) {
sDate2 = line.substring(DATE_START_POS, DATE_END_POS).trim();}
if (sDate1.equals("")){
sDate1 = sDate2;}
SimpleDateFormat formatter=new SimpleDateFormat("MMM dd, yyyy");
try {
date=formatter.parse(sDate1);
} catch (ParseException e) {
e.printStackTrace();
}
sFirm = line.substring(FIRM_START_POS, FIRM_END_POS);
sOffice = line.substring(OFFICE_START_POS, OFFICE_END_POS);
sAccount = line.substring(ACCOUNT_START_POS,
ACCOUNT_END_POS);
lineCounter++;
globalLineCounter++;
sData.append(line.substring(0, END_OF_DATA)).append("\n");
} else {
// Instantiate New Statement Object
Statement stmt = new Statement(sAccount, sOffice, sFirm,
date, sData.toString());
// Add to collection
statements.add(stmt);
// log.info("-----------NEW STATEMENT--------------");
sData.setLength(0);
lineCounter = 1;
}
prevCode = newCode;
}
return statements;
}
STACKTRACE: Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dbPopulator' defined in class path resource [app-context.xml]: Invocation of init method failed; nested exception is java.lang.OutOfMemoryError: Java heap space at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1401) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:512) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:290) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:287) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:557) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:842) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:416) at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139) at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:93) at Main.main(Main.java:11) Caused by: java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:2882) at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100) at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:390) at java.lang.StringBuffer.append(StringBuffer.java:224) at services.GMILogParser.parseGMIFile(GMILogParser.java:133) at services.DBPopulator.init(DBPopulator.java:27) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1529) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1468) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1398) ... 12 more