From c5986982525d9089fa5f6223f02dabda4a9167a2 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Wed, 5 Sep 2018 15:54:36 -0500 Subject: [PATCH] [Xamarin.Android.Build.Tasks] should Dispose AssemblyDefinition Reviewing our codebase, we found a place where the `BuildApk` task was calling an overload for `MonoAndroidHelper.IsReferenceAssembly`. This presented two problems: 1. It was using the `InMemory` option 2. We were not calling `Dispose()`! Case No.1 was bad, since we basically load every assembly into memory! foreach (ITaskItem assembly in ResolvedUserAssemblies) { if (MonoAndroidHelper.IsReferenceAssembly (assembly.ItemSpec)) { //... foreach (ITaskItem assembly in ResolvedFrameworkAssemblies) { if (MonoAndroidHelper.IsReferenceAssembly (assembly.ItemSpec)) { Likewise, we need to call `Dispose` here, since a lock could be held on the file here on Windows. The changes here made `BuildApk` slower (and more correct!), but the overall build time better. Before: 5890 ms BuildApk 1 calls Time Elapsed 00:01:02.59 After: 6377 ms BuildApk 1 calls Time Elapsed 00:00:59.37 I think the `AssemblyDefinition` instances must have been getting cleaned up later in the build by the GC (if we were lucky), and also used *a lot* more memory. This would contribute to overall build time. --- .../Utilities/MonoAndroidHelper.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.cs b/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.cs index a007664c548..6d694dd0fe9 100644 --- a/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.cs +++ b/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.cs @@ -307,8 +307,9 @@ public static bool IsFrameworkAssembly (string assembly, bool checkSdkPath) public static bool IsReferenceAssembly (string assembly) { - var a = AssemblyDefinition.ReadAssembly (assembly, new ReaderParameters () { InMemory = true, ReadSymbols = false, }); - return IsReferenceAssembly (a); + var rp = new ReaderParameters { ReadSymbols = false }; + using (var a = AssemblyDefinition.ReadAssembly (assembly, rp)) + return IsReferenceAssembly (a); } public static bool IsReferenceAssembly (AssemblyDefinition assembly)