Using Memory Efficiently When You Build Large Projects
Large projects often contain many sub-projects and other dependencies, and these may consume lots of system memory at build time. When available system memory is decreased, system performance may also be decreased. MSBuild 3.5 eases this problem by unloading projects from memory as they finish building but retaining their build results in a cache for later retrieval.
In earlier versions of MSBuild, projects remained in memory after they were built. MSBuild 3.5 introduces a task property named UnloadProjectsOnCompletion, which lets you remove a project from memory after it has completed building.
However, when a project has been unloaded from memory, it cannot be reloaded in the same build instance. Because a build often has targets that must be called to gather information in a project, unloading a project from memory during a build may cause problems. To resolve this, MSBuild 3.5 introduces another property named UseResultsCache, which can be used to cache the target results (for example, build results, items, and properties) of all projects that are being built.
Because a project occupies more memory than its build results, unloading the project but retaining its results is a more efficient use of memory. UnloadProjectsOnCompletion and UseResultsCache work together to improve build performance not only by freeing memory, but also by enabling MSBuild to retrieve build results directly from memory instead of files on disk.
The following example demonstrates how to use UnloadProjectsOnCompletion and UseResultsCache. In this example, there are two projects, MyProj1.proj and MyProj2.proj.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Target Name="default"> <Message Text="Project: MyProj1. Target: default" /> <CallTarget Targets="Normal" UseResultsCache="true"/> </Target> <Target Name="Normal" Outputs="Someoutput from second target"> <Message Text="Project: MyProj1. Target: second" /> </Target> </Project>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Target Name="default"> <Message Text="Project: MyProj2.proj Target: default" /> <MSBuild Projects=" MyProj1.proj" Targets="default" UnloadProjectsOnCompletion="true" /> <MSBuild Projects=" MyProj1.proj" Targets="Normal" UnloadProjectsOnCompletion="true" > <Output TaskParameter="TargetOutputs" PropertyName="TargetOutput"/> </MSBuild> <Message Text="Output from project: MyProj2.proj target: second = $(TargetOutput)" /> </Target> </Project>
When you build MyProj2.proj on the command line by using msbuild.exe MyProj2.proj /tv:3.5, you should see the output of target Normal from MyProj1 printing from MyProj2.