The string occupies a large amount of memory in any application. In particular, the CHAR [] array containing the independent UTF-16 character contributes the most to the consumption of JVM memory-because each character occupies 2 digits.
30%of the memory is actually very common. Not only because the string is the best format for us, but also because the popular HTTP API uses a large number of string. Using the Java 8 UPDATE 20, we can now contact a new feature, called a string to go heavy. This feature requires the G1 garbage recyrior, which is closed by default.
The string is re -used to re -use the internal of the string is actually the Char array and the feature of the final, so JVM can manipulate them arbitrarily.
The developer considers a lot of strategies for the string of string, but the final implementation is used in the final implementation:
Whenever the garbage recovery device accesses the String object, it will mark the Char array. It obtained the Hash Value of the Char array and existing it with a weak reference to the array. As long as the garbage recyrior finds another string, and this string and the Char array have the same Hash Code, then the two are compared with one character and one character.
If they just match, a string will be modified, pointing to the Char array of the second string. The first Char array is no longer cited, so it can be recycled.
Of course, this entire process brings some expenses, but it is controlled by a very tight upper limit. For example, if a character is not found to be repeated, it will no longer be checked for a period of time.
So how does this feature work? First of all, you need to just release the Java 8 UPDATE 20, and then follow this configuration: -xmx256m -xx:+useg1gc to run the following code:
Public Class Lotsofstrings {Private Static Final LinkEdlist <string> Lots_of_Strings = New LINKEDList <() (); xception {int design = 0; about (true) {for (int i = 0; i < 100; i++) { for (int j = 0; j < 1000; j++) { LOTS_OF_STRINGS.add(new String("String " + j)); } } iteration++; System.out.println("Survived Iteration: " + iteration); thread.sleep (100);}}}
This code will be reported to OutofMemoryerror after 30 iterations.
Now, open the string to go heavy, use the following configuration to run the above code:
-Xmx256m -xx:+useg1gc -XX:+UsestringDeduplication -XX:+PrintstringupLicationStator
At this time, it can run longer, and it will only end after 50 iterations.
JVM has also printed what it has done, let's take a look:
[GC Concurrent-String-Deduplication, 4658.2K-> 0.0B (4658.2K), AVG 99.6%, 0.0165023 SECS] [Last EXEC: 0.0165023 SECS, IDLE: 0.0953764 SECS: Blocked: 0/0.0000000 secs] [INSPECTD: 119538] [SKIPPD: 0 (0.0%)] [Hashed: 119538 (100.0%)] [KNOWN: 0 (0.0%)] [New: 119538 (100.0%) 4658.2k] [DedupLicated: 119538 (100.0%) 4658.2k (100.0.0.0 ] [Young: 372 (0.3%) 14.5K (0.3%)] [OLD: 119166 (99.7%) 4643.8K (99.7%)] [Total Exec: 4/0.0802259 SECS, IDLE: 4/0.6491928 SECS, BLOCKED : 0/0.0000000 secs] [Inspected: 557503] [Skipped: 0( 0.0%)] [Hashed: 556191( 99.8%)] [Known: 903( 0.2%)] [New: 556600( 99.8%) 21.2M] [ Deduplicated: 554727 (99.7%) 21.1m (99.6%)] [Young: 1101 (0.2%) 43.0k (0.2%)] [OLD: 553626 (99.8%) 21.1m (99.8%)] [table] [Memory usage : 81.1k] [size: 2048, min: 1024, MAX: 16777216] [Entries: 2776, Load: 135.5%, Cached: 0, Added: 2776, Removed: 0] [Resize Count: 1, Shrink Threeold: 13 65 (65 ( 66.7%), Grow Threshold: 4096 (200.0%)] [Rehash Count: 0, Rehash Threshold: 120, Hash Seed: 0x0] [Age Threshold: 3] [Queue] [Dropped: 0]
For convenience, we don't need to calculate the addition of all data by ourselves, and it is enough to use it conveniently.
The above code segment stipulates that the string is reached heavy. It took 16ms to check about 120 k string.
The above features are just launched, which means that it may not be comprehensively reviewed.具体的数据在实际的应用中可能看起来有差别,尤其是那些应用中字符串被多次使用和传递,因此一些字符串可能被跳过或者早就有了hashcode(正如你可能知道的那样, A String Hash Code was lazily loaded).
In the above cases, all the string is heavy, and 4.5MB of data is removed in memory.
[Table] Part of the statistical information about the internal tracking table is given.
So, what is the difference between string weighting and string residence? In fact, the string depends on it is similar to the residence. Except for the reserved mechanism, the entire string instance is reused, not just the character array.
The controversy of the creator of the JDK Enhancement Proposal 192 is that developers often do not know where to put the resident string is appropriate, or it is hidden by the framework. As I wrote, when I encounter a copy string string (Like the name of the country), you need some common sense. Strings are heavy, which is also good for the string copy of the application in the same JVM. It also includes the XML SCHEMAS, URLS, and jar names. Multiple string.
When the string stays in the application thread, when the garbage recovery is asynchronous and transmitted, the strings will not increase the consumption during runtime. This also explains why we find Thread in the code above. SLEEP (). If there is no Sleep, it will add too much pressure to GC, so that the string will not happen at all. However, this is only a problem that the example code will occur. Use a few milliseconds when we go heavy.