The code you posted will not be a memory leak. However, the while (true)
will never be completed, because s
will never be null
in the place where you tested it.
Allows you to slightly change it so that it "works"
public static void read(BufferedReader br) throws Exception { long length = 0; String s = ""; while (true) { String ss = br.readLine(); if (ss == null) { break; } s += ss; length += ss.length(); } System.out.println("Read: " + (length/1024/1024) + " MB"); }
This code is not a memory leak, because the lines created in the method will be candidates for garbage collection when the method returns (if not earlier).
Every time we do s += ss;
, a new line is created consisting of all characters currently in s
and characters in ss
. Assuming that there are N lines containing the average value of L characters, the operator s += ss;
will be called N times, will create N lines and copy on average (N * L)^2 / 2
2/2 characters.
However, there is a good reason to make StringBuilder
, which means reducing the number of line strings and copying characters that continue. Let's rewrite the method to use StringBuilder
; those. replacement for StringBuffer
that is not synchronized.
public static void read(BufferedReader br) throws Exception { long length = 0; StringBuilder sb = new StringBuilder(sb); while (true) { String ss = br.readLine(); if (ss == null) { break; } sb.append(ss); length += ss.length(); } System.out.println("Read: " + (length/1024/1024) + " MB"); }
This version redistributes the internal array of StringBuilder characters no more than log2(N)
times and copies no more than 2 * N * L
characters.
Summary - using StringBuilder is a good idea, but not due to memory leaks. If you have a memory leak, it is not in the source code sample or in the fixed version.
Stephen c
source share