Note that there are some explanatory texts on larger screens.

plurals
  1. PODebugging Java Out of Memory Error
    primarykey
    data
    text
    <p>I'm still a relatively new programmer, and an issue I keep having in Java is Out of Memory Errors. I don't want to increase the memory using -Xmx, because I feel that the error is due to poor programming, and I want to improve my coding rather than rely on more memory.</p> <p>The work I do involves processing lots of text files, each around 1GB when compressed. The code I have here is meant to loop through a directory where new compressed text files are being dropped. It opens the second most recent text file (not the most recent, because this is still being written to), and uses the Jsoup library to parse certain fields in the text file (fields are separated with custom delimiters: "|nTa|" designates a new column and "|nLa|" designates a new row).</p> <p>I feel there should be no reason for using a lot of memory. I open a file, scan through it, parse the relevant bits, write the parsed version into another file, close the file, and move onto the next file. I don't need to store the whole file in memory, and I certainly don't need to store files that have already been processed in memory.</p> <p>I'm getting errors when I start parsing the second file, which suggests that I'm not dealing with garbage collection. Please have a look at the code, and see if you can spot things that I'm doing that mean I'm using more memory than I should be. I want to learn how to do this right so I stop getting memory errors!</p> <pre><code>import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; import java.util.TreeMap; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import org.jsoup.Jsoup; public class ParseHTML { public static int commentExtractField = 3; public static int contentExtractField = 4; public static int descriptionField = 5; public static void main(String[] args) throws Exception { File directoryCompleted = null; File filesCompleted[] = null; while(true) { // find second most recent file in completed directory directoryCompleted = new File(args[0]); filesCompleted = directoryCompleted.listFiles(); if (filesCompleted.length &gt; 1) { TreeMap&lt;Long, File&gt; timeStamps = new TreeMap&lt;Long, File&gt;(Collections.reverseOrder()); for (File f : filesCompleted) { timeStamps.put(getTimestamp(f), f); } File fileToProcess = null; int counter = 0; for (Long l : timeStamps.keySet()) { fileToProcess = timeStamps.get(l); if (counter == 1) { break; } counter++; } // start processing file GZIPInputStream gzipInputStream = null; if (fileToProcess != null) { gzipInputStream = new GZIPInputStream(new FileInputStream(fileToProcess)); } else { System.err.println("No file to process!"); System.exit(1); } Scanner scanner = new Scanner(gzipInputStream); scanner.useDelimiter("\\|nLa\\|"); GZIPOutputStream output = new GZIPOutputStream(new FileOutputStream("parsed/" + fileToProcess.getName())); while (scanner.hasNext()) { Scanner scanner2 = new Scanner(scanner.next()); scanner2.useDelimiter("\\|nTa\\|"); ArrayList&lt;String&gt; row = new ArrayList&lt;String&gt;(); while(scanner2.hasNext()) { row.add(scanner2.next()); } for (int index = 0; index &lt; row.size(); index++) { if (index == commentExtractField || index == contentExtractField || index == descriptionField) { output.write(jsoupParse(row.get(index)).getBytes("UTF-8")); } else { output.write(row.get(index).getBytes("UTF-8")); } String delimiter = ""; if (index == row.size() - 1) { delimiter = "|nLa|"; } else { delimiter = "|nTa|"; } output.write(delimiter.getBytes("UTF-8")); } } output.finish(); output.close(); scanner.close(); gzipInputStream.close(); } } } public static Long getTimestamp(File f) { String name = f.getName(); String removeExt = name.substring(0, name.length() - 3); String timestamp = removeExt.substring(7, removeExt.length()); return Long.parseLong(timestamp); } public static String jsoupParse(String s) { if (s.length() == 4) { return s; } else { return Jsoup.parse(s).text(); } } } </code></pre> <p>How can I make sure that when I finish with objects, they are destroyed and not using any resources? For example, each time I close the GZIPInputStream, GZIPOutputStream and Scanner, how can I make sure they're completely destroyed? </p> <p>For the record, the error I'm getting is:</p> <pre><code>Exception in thread "main" 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:572) at java.lang.StringBuilder.append(StringBuilder.java:203) at org.jsoup.parser.TokeniserState$47.read(TokeniserState.java:1171) at org.jsoup.parser.Tokeniser.read(Tokeniser.java:42) at org.jsoup.parser.TreeBuilder.runParser(TreeBuilder.java:101) at org.jsoup.parser.TreeBuilder.parse(TreeBuilder.java:53) at org.jsoup.parser.Parser.parse(Parser.java:24) at org.jsoup.Jsoup.parse(Jsoup.java:44) at ParseHTML.jsoupParse(ParseHTML.java:125) at ParseHTML.main(ParseHTML.java:81) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload