Record thisArticleThe source of inspiration comes from a small debate with my colleagues before I leave work today. In a project I have developedCode:
Public String toxml () {string strxml = string. empty; try {memorystream MS = new memorystream (); xmlserializer xml = new xmlserializer (this. getType (); XML. serialize (MS, this); byte [] arr = Ms. toarray (); strxml = encoding. utf8.getstring (ARR, 0, arr. length); Return strxml;} catch {return "";}}
My colleagues said that resources such as memorystream should be automatically released using packages; otherwise, memory leakage may occur. I also agree that using should be used for using. However, because there are a lot of such style code in the original project (for some historical reasons), if one-to-one modification is required, the workload is too large, time is not allowed. So I evaluated in my heart: if I don't change it, what is the risk of this code?
I think many people know that using (resource res = new resrouce) {} is actually equivalent
Resource res = new resrouce
Try {}
Catch {}
Finally {Res. Dispose ();}
Compared with the existing code, the difference is that the resource does not call dispose () to release, but the CLR has a powerful GC (garbage collection) mechanism. After the method is called, The createdManagedIf resources are no longer used, they will also be listed as recyclable objects by GC. Therefore, even if developers do not manually call dispose, CLR will do this for us, the time may be later.
So we have the following test:
1. Create a class for Example
Using system; using system. collections. generic; using system. LINQ; using system. text; using system. io; using system. XML. serialization; namespace model {public class sampleclass {public string name {set; get;} Public String toxmlnousing () {string strxml = string. empty; try {memorystream MS = new memorystream (); xmlserializer xml = new xmlserializer (this. getType (); XML. serialize (MS, this); byte [] arr = Ms. toarray (); strxml = encoding. utf8.getstring (ARR, 0, arr. length); Return strxml;} catch {return "" ;}} Public String toxmlwithusing () {string strxml = string. empty; try {using (memorystream MS = new memorystream () {xmlserializer xml = new xmlserializer (this. getType (); XML. serialize (MS, this); byte [] arr = Ms. toarray (); strxml = encoding. utf8.getstring (ARR, 0, arr. length);} return strxml;} catch {return "";}}}}
Toxml is divided into two versions (one without using and the other with using) for test convenience)
2. Create another consoleProgram(Named withusing), write a test code:
Using system; using system. diagnostics; using model; namespace withusing {class program {static void main (string [] ARGs) {console. writeline ("start tossing-withusing... "); stopwatch watch = new stopwatch (); int max = 100000; watch. reset (); watch. start (); For (INT I = 0; I <Max; I ++) {sampleclass c = new sampleclass () {name = I. tostring (). padleft (1024, '0')}; C. toxmlwithusing ();} watch. stop (); console. WRI Teline ("completed, {0} Total Operation Time: {1} milliseconds, average {2} milliseconds/time! ", Max, watch. elapsedmilliseconds, watch. elapsedmilliseconds/(decimal) max); console. readkey ();}}}
3. Create a console program named nousing and write a test code:
Using system; using system. diagnostics; using model; namespace nousing {class program {static void main (string [] ARGs) {console. writeline ("start tossing-nousing... "); stopwatch watch = new stopwatch (); int max = 100000; watch. reset (); watch. start (); For (INT I = 0; I <Max; I ++) {sampleclass c = new sampleclass () {name = I. tostring (). padleft (1024, '0')}; C. toxmlnousing ();} watch. stop (); console. writeline ("Completed, {0} Total Operation Time: {1} milliseconds, average {2} milliseconds/time! ", Max, watch. elapsedmilliseconds, watch. elapsedmilliseconds/(decimal) max); console. readkey ();}}}
After compilation, run the two programs at the same time, and use the task manager to observe the memory usage:
After repeated operations and comparisons, we found that the memory occupied by the two instances was almost identical. This shows that GC is still very powerful!
In addition, the execution time is faster without using, which is also easy to understand: Using using is equivalent to calling the dispose () method every time, which brings about some system overhead; instead of using, GC will be performed at appropriate timeBatchResources are recycled to improve performance. (Of course: This conclusion is not intended to mislead everyone without using. It is recommended for using! My intention is that you should analyze specific issues, not simply dogmatism, and blindly trust some mainstream ideas.)