简体   繁体   中英

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

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.

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.

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.

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.

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 All literal strings and string-valued constant expressions are interned. String literals are defined in §3.10.5 of the Java Language Specification

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM