Several string errors

Source: Internet
Author: User
Document directory
  • Performance Considerations

I debugged a program yesterday and found that the memory could not be released, and finally found that it was caused by the incorrect use of the string. This prompted me to study the string type carefully today, I found that many of my previous understandings of string are incorrect. I feel that this misunderstanding is still quite typical. So I wrote this article to discuss it with you.

1. append a variable of the string type, or the New String object after modification is resident (interned.

As shown in the following code:

String S1 = "ABCD ";
String S2 = S1 + "E ";

I used to assume that S2 is resident, but this is not the case. The string. isinterned method is used to detect that S2 is non-resident. Later studies found that only constant strings will reside by default. Other string variables, even if they are constructed using new string, do not reside by default unless they are forcibly resident using string. Intern. Later, I will mention the impact of resident on memory. I think it is still a memory consideration for Microsoft to prevent all strings from resident.

2. After the string variable is no longer referenced, the CLR will automatically release its memory through GC.

String S1 = "ABCD ";
S1 = NULL;

The code above assumes that S1 = NULL is no longer referenced in the "ABCD" string. If no other reference points to this string, GC releases the "ABCD" memory. The actual result is no. Because S1 is assigned a constant, the "ABCD" string is resident and the resident string cannot be automatically released before the process ends. Worse, a large number of string variables in the program I debugged yesterday were used. intern forced resident, which causes me to release all the Managed Objects and still cannot release the memory of about 30 mb.

Unfortunately, the Chinese version of Microsoft's msdn is string. the performance consideration section is missing in intern's help information. I guess most Chinese programmers, including me, are too lazy to read English. Sorry, Microsoft's help in Chinese does not know why the most important part is missing. The following section describes performance consideration in English help.

Performance Considerations

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. the reason is that the CLR's reference to the interned String object can persist after your application, or even your application domain, terminates. second, to intern a string, you must first create the string. the memory used by the string object must still be allocated, even though the memory will eventually be garbage collected.

The.. NET Framework Version 2.0 introduces the compilationrelaxations .. ::. nostringinterning enumeration member. the nostringinterning member marks an assembly as not requiring string-literal interning. you can apply nostringinterning to an assembly using the compilationrelaxationsattribute attribute. also, when you use the native image generator (ngen.exe) to compile an assembly in advance of Run Time, strings are not interned into SS modules.

After reading the help in English, we can see that the strings after intern cannot be released.

3. If two strings are referenced differently, they can only be compared using equal.

I have always assumed that if two string types are compared with the = Operator, they will be compared for reference. Therefore, if two strings are referenced differently, you can only use equal to compare whether they are equal.

For example, the following statement

String S2 = new stringbuilder (). append ("my"). append ("test"). tostring ();
String S3 = new stringbuilder (). append ("my"). append ("test"). tostring ();

Compare its reference using the following method:

Console. writeline (object) S3 = (object) S2 );

The result is false, that is, S2 and S3 point to different references.

So I think console. the result of writeline (S3 = S2); is false, because string is the reference type, use the = Operator to compare the reference type variables. If the two variables have different references, even if the values are the same, it also returns false. however, I was surprised by the running results. The returned value is true.

So I searched the internet and finally found the reason.

The string equal sign operator is special, and its source code is as follows:

=== Equality operator on string type (C #) ====

// The = Operator overload msil:
. Method public hidebysig specialname static bool
Op_equality (string a, string B) cel managed
{
. Maxstack 8
L_0000: ldarg.0
L_0001: ldarg.1
L_0002: Call bool system. String: equals (
String, string)
L_0007: Ret
}

From this source code, we can see that. Net calls the system. String: equals static method in the string equal sign operator for comparison. The code for this static method is as follows.


// Determines whether two strings match.

Public static bool equals (string a, string B ){

If (object) A = (object) B ){

Return true;

}

 

If (object) A = NULL | (object) B = NULL ){

Return false;

}

 

Return response shelper (A, B );

}

From this code, we can see that when the = Operator is compared between the two string types, we first compare whether the references are equal. If not, we will call the comparison shelper to check whether the values are equal. This is what we can see when the = Operator is used to compare two strings with different references but the same value to get true.Cause.

Some Suggestions

From the perspective of time performance, if the string is resident, then use the = Operator to compare and the two strings to be compared will be very fast if they are equal. However, considering space efficiency,

If all strings are resident, a large amount of memory cannot be released. After constructing a string, you can perform the following operations. String constructed in this way if

If the string already exists, use the string reference after it resides. Otherwise, use the original reference. This not only improves the comparison efficiency, but also reduces the memory overhead because the string has previously been resident,

We do not need to re-apply for other memory to store the same string. Of course, calling tryintern itself may cause some performance loss, so you need to use it as needed. If the string is constructed

If it is frequently used for comparison, it is worthwhile to use tryintern for the first construction to lose some performance. Otherwise, it is not worthwhile. We recommend that you use the constructed string directly.

String S1 = "mytest ";
String S2 = new stringbuilder (). append ("my"). append ("test"). tostring ();

S2 = tryintern (S2 );
Public static string tryintern (string Str)
{
String internstr = string. isinterned (STR );

Return internstr = NULL? STR: internstr;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.