In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces the relevant knowledge of "how to implement the memory residence mechanism of C# string". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
1. String objects with the same character sequence will not be created repeatedly
First, let's prove the first conclusion: String objects with the same character sequence will not be created repeatedly. I first created a simple Console application and wrote the following program: four String objects are created in the static method BuildString, and str1 and str2,str3 and str4 have the same value. This method is executed in the Main method, and the program Block is resided by calling the Console.ReadLine method before and after execution.
Class Program {static void Main (string [] args) {Console.WriteLine ("Press any key to begin building string..."); Console.ReadLine (); BuildString (); Console.WriteLine ("Press any key to exit..."); Console.ReadLine ();} static void BuildString () {var str1 = "ABCDEFG"; var str2 = "ABCDEFG" Var str3 = "1234678"; var str4 = "1234678";}}
Now we take two memory snapshots before and after the static method (that is, when the corresponding text is output to the console) through the ANTS Memory Profiler startup code, the exe file of the Console program. By comparing the changes in the objects under the two snapshots, we find that there are three more instances of the String type.
Figure 1
We further tracked the value of the three extra strings, so we looked at the list of instances. From the screenshot below, we can clearly see that in addition to a string with the value "byteIndex", the other two values are "ABCDEFG" and "12345678", which we created in the static method BuildString. In the BuildString method, we created four String objects, but here we only see two. This undoubtedly confirms the existence of the string resident mechanism.
Figure 2
2. String resident mechanism is the same as string literal + string literal operation.
"+" is our most common string operator, and when we concatenate two strings through this operator, the string resident mechanism is still in effect. To this end, I define the BuildString approach as follows, using the same Profiling process, and you can still see exactly the same result as figure 2.
Static void BuildString () {var str1 = "ABCDEFG"; var str2 = "ABCD" + "EFG"; var str3 = "1234678"; var str4 = "1234" + "678";} III. String resident wit is not suitable for Variable + string literal form
Although string residency applies to the direct addition of two string values enclosed in quotation marks, if any one or two are replaced with string variables, the final result of the operation cannot be resided. We can also prove this through a step similar to the one above, for which we have made the following changes to the BuildString method. Using the Profiling process above, you still see exactly the same result as figure 2, that is, whether the variable is added to a string constant or two string constants, the result of the operation "ABCDEFG1234678" is not persisted (in fact, it is already a junk object at this time, GC can recycle it).
Static void BuildString () {var str1 = "ABCDEFG"; var str2 = "1234678"; var str3 = "ABCDEFG" + str2; var str4 = str1 + "1234678"; var str5 = str1 + str2;} 4. Call string.Intern to force the result of the operation to reside
Although the result of a string concatenation operation involving a variable will not be resided, we can force it to reside by calling the string.Intern method, which forces the string represented by the passed-in parameter to be saved in the resident pool. To do this, we modify the BuildString method as follows: pass the structure of the "ABCDEFG" + str2 operation into the string.Intern static method.
Static void BuildString () {var str1 = "ABCDEFG"; var str2 = "1234678"; var str3 = string.Intern ("ABCDEFG" + str2);}
By using the Profiling process above, there is an extra "ABCDEFG1234678" in the list of newly created object (New Object) String instances.
Figure 3
5. The resident string cannot be recovered by GC
Although String is a reference type, it is not governed by GC. When GC collects, string instances of seemingly junk objects are still kept in memory. To demonstrate, we restore the BuildString method to the original code and call the GC.Collect method to force garbage collection after the method is called. Using the Profiling process above, you still see exactly the same result as in figure 2, where four supposedly junk objects (str1~str4) still exist after GC collection.
Class Program {static void Main (string [] args) {Console.WriteLine ("Press any key to begin building string..."); Console.ReadLine (); BuildString (); GC.Collect (); Console.WriteLine ("Press any key to exit..."); Console.ReadLine ();} static void BuildString () {var str1 = "ABCDEFG"; var str2 = "ABCDEFG" Var str3 = "1234678"; var str4 = "1234678";}} VI. String residency is based on the entire process
Now let's prove the final conclusion: the resident string is based on the entire process scope, not on the current AppDomain. To prove this conclusion, we can write a little more code. We borrowed from "some in-depth discussions on CLR memory management" to create the following AppDomainContext class, which is an encapsulation of an AppDomain object. The Invoke method implements the execution of an operation based on an instance of a generic type in a separate AppDomain.
Public class AppDomainContext {public AppDomain AppDomain {get; private set;} private AppDomainContext (string friendlyName) {this.AppDomain = AppDomain.CreateDomain (friendlyName);} public static AppDomainContext CreateDomainContext (string friendlyName) {return new AppDomainContext (friendlyName);} public void Invoke (Action action) {T instance = (T) this.AppDomain.CreateInstanceAndUnwrap (typeof (T). Assembly.FullName, typeof (T) .FullName); action (instance);}}
Then we implement the above BuildString method in a Foo type that inherits from MarshalByRefObject.
Public class Foo: MarshalByRefObject {public void BuildString () {var str1 = "ABCDEFG"; var str2 = "ABCDEFG"; var str3 = "1234678"; var str4 = "1234678";}}
Then in the Main method, we execute the following program. The following program simulates the creation of three AppDomain and the execution of the BuildString method within them. If string residency is based on AppDomain, there should be six String instances. But with the above Profiling process, you still see exactly the same result in figure 2, which fully proves the conclusion that the resident mechanism is based on the process rather than the AppDomain.
Static void Main (string [] args) {Console.WriteLine ("Press any key to begin building string..."); Console.ReadLine (); AppDomainContext.CreateDomainContext ("Domain A") .invoke (foo = > foo.BuildString ()); AppDomainContext.CreateDomainContext ("Domain B") .invoke (foo = > foo.BuildString ()); AppDomainContext.CreateDomainContext ("DomainC") .invoke (foo = > foo.BuildString ()); GC.Collect () Console.WriteLine ("Press any key to exit..."); Console.ReadLine ();} "how to implement the memory resident mechanism of C# string" is introduced here. Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.