@@ -663,24 +663,29 @@ void mi_cdecl _mi_process_done(void) {
663663 if (process_done ) return ;
664664 process_done = true;
665665
666+ // get the default heap so we don't need to acces thread locals anymore
667+ mi_heap_t * heap = mi_prim_get_default_heap (); // use prim to not initialize any heap
668+ mi_assert_internal (heap != NULL );
669+
666670 // release any thread specific resources and ensure _mi_thread_done is called on all but the main thread
667671 _mi_prim_thread_done_auto_done ();
668672
673+
669674 #ifndef MI_SKIP_COLLECT_ON_EXIT
670675 #if (MI_DEBUG || !defined(MI_SHARED_LIB ))
671676 // free all memory if possible on process exit. This is not needed for a stand-alone process
672677 // but should be done if mimalloc is statically linked into another shared library which
673678 // is repeatedly loaded/unloaded, see issue #281.
674- mi_collect ( true /* force */ );
679+ mi_heap_collect ( heap , true /* force */ );
675680 #endif
676681 #endif
677682
678683 // Forcefully release all retained memory; this can be dangerous in general if overriding regular malloc/free
679684 // since after process_done there might still be other code running that calls `free` (like at_exit routines,
680685 // or C-runtime termination code.
681686 if (mi_option_is_enabled (mi_option_destroy_on_exit )) {
682- mi_collect ( true /* force */ );
683- _mi_heap_unsafe_destroy_all (); // forcefully release all memory held by all heaps (of this thread only!)
687+ mi_heap_collect ( heap , true /* force */ );
688+ _mi_heap_unsafe_destroy_all (heap ); // forcefully release all memory held by all heaps (of this thread only!)
684689 _mi_arena_unsafe_destroy_all ();
685690 _mi_segment_map_unsafe_destroy ();
686691 }
0 commit comments