1

Use case:
Fetch all the clips URL from s3 as list of strings . Then Submit the list clip to summary.

   public static void main(String[] args) {
    List<String> randomStringList = getListOfRandomeStrings();

}


static List<String> getListOfRandomeStrings() {
    List<String> randomStringList = new ArrayList<>();
    // Add 2k strings to randomStringList
    return randomStringList;
}

static void iterateList(List<String> randomStrings) {

    // Iterate and print strings
}

Questions

1) When the Strings from string pool will be garbage collected?
2) Is there any way to clean the strings?
3) Does using Weak-reference helps?

Refereed this link, but not still not clear When will a string be garbage collected in java

user3024119
  • 190
  • 1
  • 2
  • 11
  • From my understanding, they'll be put into a queue of sorts for garbage collection when they're done being used (i.e. out of scope). I think there is a command that will force garbage collection but I'd just let java decide when to do it – Dustin Nieffenegger Feb 08 '19 at 08:28
  • 2
    @DustinNieffenegger There is not command that *forces* the GC to get active. You kindly ask the JVM to "please consider doing a GC run now", what the JVM does about your request is up to the JVM. – GhostCat Feb 08 '19 at 09:50
  • I looked into it more and I agree! It is merely a suggestion, not a requirement. Even with a call to `system.runFinalization()` (which is also just a suggestion) there is no guarantee that garbage collection will be done immediately. This is why, again, I say *just let java decide when to do it!* – Dustin Nieffenegger Feb 08 '19 at 18:30

3 Answers3

4

1) There is no way to predict Garbage Collection in JVM.

2) There is no way to force Garbage Collection in JVM.

3) Storing them as Weak-references will help to clear them (possibly) earlier:

A weakly referenced object is cleared by the Garbage Collector when it’s weakly reachable.

Weak reachability means that an object has neither strong nor soft references pointing to it. The object can be reached only by traversing a weak reference.

First, the Garbage Collector clears a weak reference, so the referent is no longer accessible. Then the reference is placed in a reference queue where we can obtain it from.

You may call System.gc() to suggest JVM to Collect Garbage, but there are no strong guarantees.

If you're running out of memory, theoretically, weak and soft references are first candidates for removal.

2000 of avegare url-strings will kepp approximately several Megabytes of memory (What is a "meh" even for a regular machine).

So I would rather suggest to do in in a natural way - put them out of scope when you don't need them and don't bother until you really need to care about memory optimization.

J-Alex
  • 6,881
  • 10
  • 46
  • 64
  • 1
    So is yours. Always nice to see how multiple answers come together and build more than the sum of the parts ;-) – GhostCat Feb 08 '19 at 08:49
  • Ok let me ask the question in different way if we create Weak-reference for list of strings. Will the strings from the string pool be deleted when the list object is delete. As per my understanding no. So i wanted to know when string pools will be garbage collected. – user3024119 Feb 08 '19 at 09:01
  • I am facing OutOfMemory error. Only thing we do is load 1k strings sort and pass it to other component. – user3024119 Feb 08 '19 at 09:03
  • 1
    @user3024119 Then Either your JVM is started with not enough memory, or, more likely, your code is **buggy** and creates a real memory leak somewhere. So, the real answer here is: enable GC logging for your JVM, and start studying what is **really** going on. – GhostCat Feb 08 '19 at 09:07
  • 2
    As addendum to @GhostCat's comment, a weak reference is no magic. If objects don't get garbage collected, there is at least one reference preventing it. Creating an additional weak reference doesn't change that. The crucial thing is the already existing reference. You have to identify it and if unneeded, just remove it. But if the reference is needed, there is no way around adding more memory. – Holger Feb 08 '19 at 16:57
3

Hmm, why do you want things to be collected immediately?!

The JVM is responsible for managing its memory. It will do garbage collection when it considers that to be necessary.

Of course: the sooner your references go "out of life", the quicker objects become eligible for garbage collection, and of course, weak references can help with that.

But the real answer: don't get into premature optimisation. If you think there is a problem, then do proper benchmarking. You are right now making assumptions about a hypothetical problem, and a hypothetical solution. That is rarely a good starting point!

And please note: Strings are created in string pool. That is only true for literal strings from source code. Your strings are all created via new String() in the end. See here for further reading.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Wisely, as always :) – J-Alex Feb 08 '19 at 08:41
  • why do you want things to be collected immediately? We process 100 jobs per sec. So we keep on creating 1k strings per job. We will soon run into Out of memory. – user3024119 Feb 08 '19 at 08:57
  • Strings are created in string pool. So wanted to know when it will be garbage collected. – user3024119 Feb 08 '19 at 08:59
  • @user3024119 It looks for me that you're trying to solve the real problem with the only theoretical assumptions. Start profiling and find exact numbers. You're chasing ghosts now. – J-Alex Feb 08 '19 at 09:21
  • @user3024119 first, as already said, string are *not* "created in the pool", but even if your code placed them in the pool explicitly, it had no impact on the garbage collection. They still get collected when unused. Generally, don't try to solve a problem unless you have a problem. – Holger Feb 08 '19 at 16:48
0

One way to do this is to store the strings in a ByteBuffer using direct memory and then use sun.misc.Cleaner to clear it out as soon as you are done. From java 9 on, the Cleaner has moved to into java.lang.ref (detailed here). There are use cases where you need to handle a large number of Strings for a short while and not stress the gc.
I've used the Cleaner when it was in sun.misc, instead of posting my own code I'll provide this rather detailed example.

Erik
  • 2,013
  • 11
  • 17
  • @GhostCat With Java9, cleaner has moved to java.lang.ref but otherwise you are correct. It's more likely there's a resource leak in the code. There are, however, use cases where it is interesting to be able to clear strings (or the equivalent) once you are done with them and I wanted to illuminate some options there. – Erik Feb 08 '19 at 11:00
  • If you edit your answer accordingly, maybe adding a link to the Java9 javadoc, my upvote will be with you ;-) – GhostCat Feb 08 '19 at 11:27
  • I've read the question multiple times and still don't get which actual problem you want to solve. The OP asked a few very generic questions. – Holger Feb 08 '19 at 16:46