From 13c254d822d07894deab8bbd8af906ba39ba0a76 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Thu, 20 May 2021 18:57:45 +0200 Subject: [PATCH] [runtime] Release the block_wrapper_queue and xamarin_wrapper_hash dictionaries upon process exit. While not strictly necessary to not leak (because the process is exiting anyway), it makes it easier to read leak reports, because these dictionaries won't show up as leaked memory anymore. Before: There were 258096 MonoObjects created, 258015 MonoObjects freed, so 81 were not freed. (dynamic registrar) There were 205834 MonoObjects created, 205833 MonoObjects freed, so 1 were not freed. (static registrar) After: There were 258104 MonoObjects created, 258025 MonoObjects freed, so 79 were not freed. (dynamic registrar) There were 205834 MonoObjects created, 205834 MonoObjects freed, so no leaked MonoObjects. (static registrar) --- runtime/monotouch-main.m | 2 ++ runtime/runtime.m | 16 ++++++++++++++++ runtime/xamarin/runtime.h | 1 + 3 files changed, 19 insertions(+) diff --git a/runtime/monotouch-main.m b/runtime/monotouch-main.m index d0c0a2d55abe..0a9a0c2cc46f 100644 --- a/runtime/monotouch-main.m +++ b/runtime/monotouch-main.m @@ -495,6 +495,8 @@ - (void) memoryWarning: (NSNotification *) sender xamarin_mono_object_release (&assembly); + xamarin_release_static_dictionaries (); + xamarin_bridge_shutdown (); return rv; diff --git a/runtime/runtime.m b/runtime/runtime.m index 0163bbdaf5dd..c7728faebd63 100644 --- a/runtime/runtime.m +++ b/runtime/runtime.m @@ -2070,6 +2070,22 @@ -(void) xamarinSetFlags: (enum XamarinGCHandleFlags) flags; return rv; } +void +xamarin_release_static_dictionaries () +{ +#if defined (CORECLR_RUNTIME) + // Release static dictionaries of cached objects. If we end up trying to + // add objects to these dictionaries after this point (on a background + // thread), the dictionaries will be re-created (and leak) - which + // shouldn't be a problem, because at this point the process is about to + // exit anyway. + pthread_mutex_lock (&wrapper_hash_lock); + xamarin_mono_object_release (&block_wrapper_queue); + xamarin_mono_object_release (&xamarin_wrapper_hash); + pthread_mutex_unlock (&wrapper_hash_lock); +#endif +} + void xamarin_set_use_sgen (bool value) { diff --git a/runtime/xamarin/runtime.h b/runtime/xamarin/runtime.h index a67df5d83ed6..8b1fd409223a 100644 --- a/runtime/xamarin/runtime.h +++ b/runtime/xamarin/runtime.h @@ -230,6 +230,7 @@ bool xamarin_set_gchandle_with_flags_safe (id self, GCHandle gchandle, enum Xa void xamarin_create_gchandle (id self, void *managed_object, enum XamarinGCHandleFlags flags, bool force_weak); void xamarin_release_managed_ref (id self, bool user_type); void xamarin_notify_dealloc (id self, GCHandle gchandle); +void xamarin_release_static_dictionaries (); int xamarin_main (int argc, char *argv[], enum XamarinLaunchMode launch_mode);