...
This noncompliant code example reads lines of text from a file and adds each one to a vector until a line with the word "quit" is encountered.
Code Block | ||
---|---|---|
| ||
class ReadNames {
private Vector<String> names = new Vector<String>();
private final InputStreamReader input;
private final BufferedReader reader;
public ReadNames(String filename) throws IOException {
this.input = new FileReader(filename);
this.reader = new BufferedReader(input);
}
public void addNames() throws IOException {
try {
String newName;
while (((newName = reader.readLine()) != null) &&
!(newName.equalsIgnoreCase("quit"))) {
names.addElement(newName);
System.out.println("adding " + newName);
}
} finally {
input.close();
}
}
public static void main(String[] args) throws IOException {
if (args.length != 1) {
System.out.println("Arguments: [filename]");
return;
}
ReadNames demo = new ReadNames(args[0]);
demo.addNames();
}
}
|
...
This compliant solution imposes a limit on the size of the file being read. This is accomplished with the Files.size()
method, which is new to Java SE 7. If the file is within the limit, we can assume the standard readLine()
method will not exhaust memory, nor will memory be exhausted by the while
loop.
Code Block | ||
---|---|---|
| ||
class ReadNames {
// ...other methods and variables
public static final int fileSizeLimit = 1000000;
public ReadNames(String filename) throws IOException {
long size = Files.size( Paths.get( filename));
if (size > fileSizeLimit) {
throw new IOException("File too large");
} else if (size == 0L) {
throw new IOException("File size cannot be determined, possibly too large");
}
this.input = new FileReader(filename);
this.reader = new BufferedReader(input);
}
}
|
...
This compliant solution imposes limits both on the length of each line and on the total number of items to add to the vector. (It does not depend on any Java SE 7 features.)
Code Block | ||
---|---|---|
| ||
class ReadNames { // ...other methods and variables public static String readLimitedLine(Reader reader, int limit) throws IOException { StringBuilder sb = new StringBuilder(); for (int i = 0; i < limit; i++) { int c = reader.read(); if (c == -1) { return ((sb.length() > 0) ? sb.toString() : null); } if (((char) c == '\n') || ((char) c == '\r')) { break; } sb.append((char) c); } return sb.toString(); } public static final int lineLengthLimit = 1024; public static final int lineCountLimit = 1000000; public void addNames() throws IOException { try { String newName; for (int i = 0; i < lineCountLimit; i++) { newName = readLimitedLine(reader, lineLengthLimit); if (newName == null || newName.equalsIgnoreCase("quit")) { break; } names.addElement(newName); System.out.println("adding " + newName); } } finally { input.close(); } } } |
...
This noncompliant code example requires more memory on the heap than is available by default.
Code Block | ||
---|---|---|
| ||
/** Assuming the heap size as 512 MB
* (calculated as 1/4th of 2 GB RAM = 512 MB)
* Considering long values being entered (64 bits each,
* the max number of elements would be 512 MB/64bits =
* 67108864)
*/
public class ReadNames {
// Accepts unknown number of records
Vector<Long> names = new Vector<Long>();
long newID = 0L;
int count = 67108865;
int i = 0;
InputStreamReader input = new InputStreamReader(System.in);
Scanner reader = new Scanner(input);
public void addNames() {
try {
do {
// Adding unknown number of records to a list
// The user can enter more IDs than the heap can support and,
// as a result, exhaust the heap. Assume that the record ID
// is a 64 bit long value
System.out.print("Enter recordID (To quit, enter -1): ");
newID = reader.nextLong();
names.addElement(newID);
i++;
} while (i < count || newID != -1);
} finally {
input.close();
}
}
public static void main(String[] args) {
ReadNames demo = new ReadNames();
demo.addNames();
}
}
|
...
A simple compliant solution is to reduce the number of names to read.
Code Block | ||
---|---|---|
| ||
// ...
int count = 10000000;
// ...
|
...
[API 2006] | Class |
java – The Java application launcher, Syntax for increasing the heap size | |
[SDN 2008] | |
[Sun 2003] | Chapter 5, Tuning the Java Runtime System, Tuning the Java Heap |
[Sun 2006] | Garbage Collection Ergonomics, Default values for the Initial and Maximum Heap Size |