-2

Please take a look at the following code snippet:

public static void main(String[] args) {
        BufferedReader reader;
        try {
            reader = new BufferedReader(new FileReader(
                    "myfile.txt"));
            String line = reader.readLine();
            while (line != null) {
                System.out.println(line);
                // read next line
                line = reader.readLine();
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

As you can see, every line of the file is read and stored in 'line' variable. Since 'line' is of type string, its content is stored in string pool. Strings stored in string pool are not collected by Java garbage collector and stay there for the entire lifetime of the program.

In case the file is very big, string pool can be bloated. Do you have any idea how to read the file without storing all of its lines in the string pool? I just was to store the file lines as any object, meaning that it will removed from heap when it's not needed.

CrazySynthax
  • 13,662
  • 34
  • 99
  • 183
  • Have you profiled your code to document that the string pool "bloat" is causing you an issue? If not, wouldn't this be possible premature optimization? – Hovercraft Full Of Eels Nov 11 '19 at 18:43
  • Note -- I've never heard of String-pool "bloat". Do you have any links to references on this problem? – Hovercraft Full Of Eels Nov 11 '19 at 18:43
  • 1
    @azurefrog Or `String`(s) you explicitly [`intern()`](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#intern--). OP *should* be using [`try-with-resources`](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html) (but that *explicit* `reader.close()` just bothers me). – Elliott Frisch Nov 11 '19 at 18:47
  • 4
    "Since 'line' is of type string, its content is stored in string pool" this is simply wrong. Strings are not stored in the string pool unless they are compile-time constants, or you call `intern` on them. – Andy Turner Nov 11 '19 at 18:48
  • @HovercraftFullOfEels, do you have any idea how to profile string pool? I tried to use jconsole and I can only profile the heap – CrazySynthax Nov 11 '19 at 18:57
  • I have no idea, but again, I've never heard of this problem and have to wonder what even generated the question, why you thought that this might be an issue. – Hovercraft Full Of Eels Nov 11 '19 at 18:59
  • This seems like a duplicate of https://stackoverflow.com/questions/18406703/when-will-a-string-be-garbage-collected-in-java. – NinePlanFailed Nov 11 '19 at 20:07
  • 1
    @HovercraftFullOfEels there were truly two problems connected with the string pool in the past. First, there was a time when all pooled strings were placed in the fixed sized PermGen, which changed with Java 7 (since Java 8, there's not even a PermGen anymore). Further, the pool is a fixed size hash table, which can lead to many collisions when overused, but in Java 7 update 40, it was changed from 1009 to 60013 (not kidding), which mitigated the effects. But even in the old versions, `intern()` did not prevent garbage collection, so putting temporary strings into it only made the code slower. – Holger Nov 12 '19 at 16:05
  • @ElliottFrisch but even if the OP was invoking `intern()` in that code, it wouldn't prevent the garbage collection of these strings, which will remove them from the pool, of course. – Holger Nov 12 '19 at 16:16
  • @Holger I was merely mentioning the second way `String`(s) might end up in the string pool; but I agree that OP's concern does not appear well founded. As I mentioned, I feel the explicit `close()` is of more concern (since this could end up in a method, and the code leaks file handles in the presence of exceptions). – Elliott Frisch Nov 12 '19 at 16:27
  • @ElliottFrisch indeed, though it's hard to say what will get into a real life code. I rarely need to print a file to the console/stdout. But if I need it and don't need charset conversions, I'd probably do a single-liner, `Files.copy(Paths.get("myfile.txt"), new FileOutputStream(FileDescriptor.out));` – Holger Nov 12 '19 at 16:36

1 Answers1

1

Only string literals is stored into the SpringPool by default until and otherwise, you call the .interm() method of the String object.

In your above example, the variable 'line' is a string object and is not part of the StringPool. You used the string literal "myfile.txt" which will be part of the StringPool

Lal Mohandas
  • 116
  • 5