Understanding the MSXML garbage collection mechanism (304227)



The information in this article applies to:

  • Microsoft XML 2.5
  • Microsoft XML 2.6
  • Microsoft XML 3.0
  • Microsoft XML 3.0 SP1
  • Microsoft XML 3.0 SP2
  • Microsoft XML 4.0
  • Microsoft XML 4.0 SP1

This article was previously published under Q304227

SUMMARY

This article explains how garbage collection works and how to tune the default behavior.

MORE INFORMATION

The MSXML parser internally uses a delayed freeing mechanism that is known as garbage collection to cause faster performance on multi-processor computers. For example, garbage collection frees the FreeThreadedDOMDocument object and the nodes from such documents. This mechanism is designed to reduce the computational cost of object destruction and improve the system throughput, which is important for server environments. However, depending on your application scenario, you may have to tune the default garbage collection behavior to optimize the performance of the application.

Generally, the garbage collection mechanism has two stages: partial garbage collection (NoFullGC) and full garbage collection (FullGC). Several internal factors trigger the partial garbage collection or full garbage collection process. Partial garbage collection can be interrupted, but full garbage collection cannot be interrupted until all of the objects that are marked for deletion are destroyed and the system resource is freed. Full garbage collection requires the suspension of all threads that use the MSXML parser in the host process. This makes the operation very expensive.

Full garbage collection may also cause a performance bottleneck when objects such as DOMDocument objects (in versions of MSXML earlier than MSXML 3.0 Service Pack 2) or FreeThreadedDOMDocument objects are frequently created and destroyed. In those specific scenarios, you can modify the registry settings to turn off full garbage collection.

The following settings are related to the garbage collection behavior when Msxml4.dll is the parser that you want to affect. The values that are shown are the default settings that are used if there are no registry entries.
REGEDIT4
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\msxml40] 
"NoFullGC"=dword:00000000
				
To enable partial garbage collection, this registry setting should be 0x00000001.

Note Modification of these default settings affects all applications that use a particular version of the MSXML parser computer-wide. Only modify these settings with extreme caution and after extensive testing with all running applications.

Performance

When you use a mix of the DOMDocument class and the FreeThreadedDOMDocument class in a multi-threaded application, you can gain both CPU and memory utilization by maintaining at least one active reference to at least one FreeThreadDOMDocument class in the process at all times. This prevents repeated initialization of various internal data structures, and allows the MSXML garbage collector to perform more efficiently. If you do not do this, too much memory may be used. The NoFullGC value determines whether full garbage collection is enabled. By default, the setting is 0, which means that full garbage collection is enabled. The NoFullGC value can be set to a non-zero value to disable the full garbage collection.
  • With MSXML 4.0 Service Pack 1 (SP1) and later, the parser implements a feature to turn off full garbage collection automatically when it detects too much contention. Therefore, do not modify this setting unless you absolutely must.
  • Although turning full garbage collection off can increase speed, the result is that the MSXML parser cannot then interrupt activities such as the loading of large XML documents or long-running XSLT transformations to free memory. This may result in an increase in overall memory usage and lead to unbounded memory consumption in some applications. Use NoFullGC only in heavily multi-threaded applications after extensive testing.
  • When full garbage collection is enabled (the default setting), you can also start full garbage collection by calling the exported DllCanUnloadNow function on the parser dynamic-link library (DLL). In a Microsoft Visual C++ program, calling CoFreeUnusedLibraries in turn invokes DllCanUnloadNow on the MSXML parser DLL. In Microsoft Visual Basic, you can use the following to invoke DllCanUnloadNow:
    Private Declare Function DllCanUnloadNow Lib "msxml3.dll" () As Long
    
    Public Sub DoGC()
    Dim ret As Long
    ret = DllCanUnloadNow()
    End Sub
    					
    Note If you use either Msxml2.dll (MSXML 2.6) or Msxml3.dll (MSXML 3.0), you must modify the registry key name to MSXML26 or MSXML30 as appropriate. If you modify the settings and MSXML is already loaded in the process, you must restart the process.

REFERENCES

For more information, click the following article number to view the article in the Microsoft Knowledge Base:

297997 PRB: MSXML performance bottleneck in ShareMutex under stress


Modification Type:MajorLast Reviewed:5/4/2005
Keywords:kbinfo KB304227