2

StringCoding line 513 https://github.com/AdoptOpenJDK/openjdk-jdk11/blob/master/src/java.base/share/classes/java/lang/StringCoding.java line 513

This ThreadLocal holds the last generated string

I'm using a very large string before returning the thread to the pool, so clearing it with

new String(new char[0]);

fixes the issue, but maybe I'm missing something.

Can anyone understand why it's there? Maybe I shouldn't clear it.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
ben or
  • 653
  • 5
  • 17
  • 3
    "fixs the issue" fixes *what* issue? `StringCoding` isn't part of the public API, so you shouldn't really have to care about this. – Andy Turner Nov 23 '20 at 16:01
  • I care because it holds the string in memory and it will not be release until the next new String which might be a very long time. also if I have a big pool each thead will hold a string and I'll run out of memory – ben or Nov 23 '20 at 16:05
  • It seems to be a thread-local cache. I haven't fully understood which case it optimizes, but it seems your problem is more related cleaning up thread locals after you are done with the current thread, right? – Hulk Nov 23 '20 at 16:12
  • 2
    @Hulk that is internal code inside the string object. as such, it's not handled/exposed externally. the question is why would it be build like this and is it problematic to clear it out. if it's standard to clear out all thread locals, even ones not set be you, then why isn't the sdk clearing it for you? is this a bug in java? "using thread pools will cause excessive memory usage/leak" (even when using built in ExecuterService) – Imbar M. Nov 23 '20 at 16:26
  • @ImbarM. there is no bug. Maybe a bit more memory is used than expected, but other than that everything appears to be fine. To quote [the accepted answer of the proposed duplicate](https://stackoverflow.com/a/3869236/2513200) "Thread local memory leaks should not normally be a major issue with bounded thread pools since any thread locals are likely to get overwritten eventually". The implementation does not know when you want to reuse that thread for something else, and that the cache will no longer be useful. It seems to be that the OP uses a load the implementation is not optimized for. – Hulk Nov 23 '20 at 17:03
  • I can get the general assumption that if it's bounded then it's not a MAJOR leak, but keeping those references in memory and hoping some day some other operation might remove them seems wrong to me. It's a "limited" leak, but still very bad. It's ok to need to know to clear out my own ThreadLocals, but to do so for internal java objects doesn't make sense, even more so when reflection is needed to solve that. If there is no other way, then something is defiantly fishy here. – Imbar M. Nov 23 '20 at 17:50
  • Whatever solves your problem with large strings, **it is not** the line `new String(new char[0]);` - there is no code path from the `String(char[])` constructor that uses or modifies `StringCoding.Result` – Thomas Kläger Nov 23 '20 at 17:54
  • Thanks @Thomas, he meant new byte[0]. – Imbar M. Nov 23 '20 at 18:02

0 Answers0