Skip to content

Commit 68058ae

Browse files
committed
runtime: reserve 16GB of heap address space on 64-bit unix
allocateHeap capped the heap at 1GB for all targets, so with -gc=conservative or -gc=precise any single allocation approaching 1GB (for example a scrypt key-derivation buffer with N=1<<20, r=8) failed with out of memory regardless of available system RAM. Reserve 16GB of virtual address space on 64-bit targets instead. The mmap is a reservation, not a commitment: pages cost physical memory only when first touched, and the existing halve-on-failure loop still adapts when the map is refused. 32-bit targets keep the 1GB cap. This is the direction the growHeap comment already points at: "If we run out of memory, we should consider increasing heapMaxSize on 64-bit systems." With this, the practical limit under the blocks GC on 64-bit hosts becomes actual system memory, matching the boehm default and big Go; true exhaustion surfaces as the OS's memory pressure handling rather than a fatal error at an arbitrary 1GB.
1 parent bdc4a21 commit 68058ae

1 file changed

Lines changed: 11 additions & 1 deletion

File tree

src/runtime/runtime_unix.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,17 @@ func allocateHeap() {
324324
// Allocate a large chunk of virtual memory. Because it is virtual, it won't
325325
// really be allocated in RAM. Memory will only be allocated when it is
326326
// first touched.
327-
heapMaxSize = 1 * 1024 * 1024 * 1024 // 1GB for the entire heap
327+
if TargetBits == 64 {
328+
// Reserve 16GB of virtual address space on 64-bit targets. This is a
329+
// reservation, not a commitment: pages cost physical RAM only when
330+
// first touched, and the halving loop below still adapts if mmap
331+
// refuses. A 1GB cap would make any single allocation approaching
332+
// 1GB (e.g. a scrypt key-derivation buffer with N=1<<20, r=8) fail
333+
// regardless of available system memory.
334+
heapMaxSize = 16 * 1024 * 1024 * 1024
335+
} else {
336+
heapMaxSize = 1 * 1024 * 1024 * 1024 // 1GB for the entire heap
337+
}
328338
for {
329339
addr := mmap(nil, heapMaxSize, flag_PROT_READ|flag_PROT_WRITE, flag_MAP_PRIVATE|flag_MAP_ANONYMOUS, -1, 0)
330340
if addr == unsafe.Pointer(^uintptr(0)) {

0 commit comments

Comments
 (0)