Does the CLR/JVM keep one single intern pool for all running .net/java apps?
Asked Answered
C

4

6

The following is an extract from MSDN:

The common language runtime conserves string storage by maintaining a table, called the intern pool, that contains a single reference to each unique literal string declared or created programmatically in your program. Consequently, an instance of a literal string with a particular value only exists once in the system.

For example, if you assign the same literal string to several variables, the runtime retrieves the same reference to the literal string from the intern pool and assigns it to each variable.

The Intern method uses the intern pool to search for a string equal to the value of str. If such a string exists, its reference in the intern pool is returned. If the string does not exist, a reference to str is added to the intern pool, then that reference is returned. .... If you are trying to reduce the total amount of memory your application allocates, keep in mind that interning a string has two unwanted side effects. First, the memory allocated for interned String objects is not likely be released until the common language runtime (CLR) terminates.

So, does this mean that CLR keeps one single intern pool for all running .net apps? Example: if a program A creates a string literal "Test" and if another program tries to create another string literal "Test", the same copy is used? The same question also applies to JVM.

Capri answered 4/7, 2011 at 8:13 Comment(0)
R
2

The CLR keeps an intern pool per instance. If you read further down the MSDN link:

If you are trying to reduce the total amount of memory your application allocates, keep in mind that interning a string has two unwanted side effects. First, the memory allocated for interned String objects is not likely be released until the common language runtime (CLR) terminates.

For Java it's also per JVM you start.

However according to this article:

This myth goes in the opposite direction of myth 2. Some people belive that internalized strings stay in the memory until the JVM ends. It may have been true a long time ago, but today the internalized strings are garbage collected if there are no more references to them. See below a slightly modified version of the program above. It clears the references to internalized strings from time to time. If you follow the program execution from jconsole, you will see that the PermGen space usage goes up and down, as the Garbage Collector reclaims the memory used by the unreferenced internalized strings.

Which means in Java interned strings can actually get GCed.

Recoil answered 4/7, 2011 at 8:18 Comment(0)
M
1

No, because it can't.
Each app runs in its own virtual memory space. You cannot share data between two memory spaces.
And consider the loading/unloading sequences. It would become very complicated and you could never remove a string.
Also note this part of your quote:

each unique literal string declared or created programmatically in your program.


OK, just reading a little further on that MSDN page:

the CLR's reference to the interned String object can persist after your application, or even your application domain, terminates.

Meddlesome answered 4/7, 2011 at 8:19 Comment(1)
Holterman - the line from MSDN - First, the memory allocated for interned String objects is not likely be released until the common language runtime (CLR) terminates. Looks like it is for CLRCark
T
0

As for Java, yes. String literals are kept in a pool per JVM. Excerpt from the JavaDoc of String#intern(): All literal strings and string-valued constant expressions are interned. String literals are defined in §3.10.5 of the Java Language Specification

Torrlow answered 4/7, 2011 at 8:20 Comment(3)
they are interned per application or for whole of JVM?Cark
As far as I know, there is one pool per JVM. In the normal case however, you're likely to have one JVM per application - that depends on the definition of application though. In a server environment the application server would run in one JVM and could host multiple (sub)applications.Torrlow
I believe the question was for a JVM running multiple applications using a separate classloader for each (e.g. a servlet container) whether it is possible that there are multiple intern pools. That would be tantamount to asking if we can load java.lang.String multiple times with different classloaders.Barcelona
H
0

As I understand for the CLR it is one per runtime, not per AppDomain. From Jeffrey Richter's "CLR Via C#"

Note that the garbage collector can't free the strings that the internal hash table refers to because the hash table holds the reference to those String objects. String objects referred to by the internal hash table can't be freed until the AppDomain is unloaded or the process terminates.

This suggests that the table is separate from the AppDomain.

JVM doesn't have this concept so there is no ambiguity. You may have different class loaders, but it is hard to imagine you would have different class loaders for String.

Holle answered 24/3, 2013 at 18:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.