[Gc] GC_heapsize and memory unmapping

Ivan Maidanski ivmai at mail.ru
Sat Nov 22 06:45:04 PST 2008


Hi!

GC_get_heap_size() should always return current heap size owned by GC (i.e. not taking into account current unmapped memory size). Otherwise, it's possible to observe a situation where the sum of GC_get_heap_size() values of 2 apps (running in parallel) would exceed the system's virtual memory size.

In my opinion, the best way to make GC_get_heap_size() return proper values is to adjust GC_heapsize and GC_large_free_bytes global values in GC_remap(), GC_unmap[_gap]() ("os_dep.c" file). The patch does this.

PS. I'm still getting sometimes assert violation in GC_merge_unmapped() "GC_ASSERT(!IS_MAPPED(nexthdr))".

Bye.
-------------- next part --------------
diff -ru bdwgc/os_dep.c updated/bdwgc/os_dep.c
--- bdwgc/os_dep.c	2008-11-20 18:57:18.000000000 +0300
+++ updated/bdwgc/os_dep.c	2008-11-22 14:49:58.000000000 +0300
@@ -2005,6 +2005,8 @@
 	  if (!VirtualFree(start_addr, free_len, MEM_DECOMMIT))
 	      ABORT("VirtualFree failed");
 	  GC_unmapped_bytes += free_len;
+	  GC_large_free_bytes -= free_len;
+	  GC_heapsize -= free_len;
 	  start_addr += free_len;
 	  len -= free_len;
       }
@@ -2019,6 +2021,8 @@
         if (result != (void *)start_addr) ABORT("mmap(...PROT_NONE...) failed");
       }
       GC_unmapped_bytes += len;
+      GC_large_free_bytes -= len;
+      GC_heapsize -= len;
 #   endif
 }
 
@@ -2046,6 +2050,8 @@
 	  if (result != start_addr) {
 	      ABORT("VirtualAlloc remapping failed");
 	  }
+	  GC_heapsize += alloc_len;
+	  GC_large_free_bytes += alloc_len;
 	  GC_unmapped_bytes -= alloc_len;
 	  start_addr += alloc_len;
 	  len -= alloc_len;
@@ -2063,6 +2069,8 @@
 	        start_addr, (unsigned long)len, errno);
 	  ABORT("Mprotect remapping failed");
       }
+      GC_heapsize += len;
+      GC_large_free_bytes += len;
       GC_unmapped_bytes -= len;
 #   endif
 }
@@ -2095,12 +2103,16 @@
 	  if (!VirtualFree(start_addr, free_len, MEM_DECOMMIT))
 	      ABORT("VirtualFree failed");
 	  GC_unmapped_bytes += free_len;
+	  GC_large_free_bytes -= free_len;
+	  GC_heapsize -= free_len;
 	  start_addr += free_len;
 	  len -= free_len;
       }
 #   else
       if (len != 0 && munmap(start_addr, len) != 0) ABORT("munmap failed");
       GC_unmapped_bytes += len;
+      GC_large_free_bytes -= len;
+      GC_heapsize -= len;
 #   endif
 }
 


More information about the Gc mailing list