win32 memory allocation fix / mmap emulation
Blaine Whittle
BWhittle@REDACTED
Fri Dec 11 02:36:36 CET 2009
This patch attempts to address the win32 memory fragmentation / OMM problem. Additionally the link step now uses LARGEADDRESSAWARE which flags the OS to allocate 3 gigs of VM to the process instead of the standard 2 (XP requires a small config change to use it, but newer OS's should be fine. Google "largeaddressaware 3g" for more info).
The memory fragmentation problem results in Erlang crashing with an OOM error. Often this occurs when the process only has between 1.1gb and 1.3gb allocated.
Here's a post where someone ran into memory issues while running mnesia on windows.
http://old.nabble.com/Is-mnesia-erlang-ETP-strong-enough--td21960047.html
The reason for the memory fragmentation is that most of Erlang's memory manager code is disabled / ifdef out for windows builds. I assume the reason for this config is the lack of MMAP on win32. However, anonymous mmap can "mostly" be emulated via VirtualAlloc and VirtualFree.
The two significant differences between VirtualAlloc and anonymous mmap are
1) Virtual memory is allocated in a much large page sizes then the standard OS page size.
2) An allocated block cannot be released piecemeal, it's all or nothing (fortunately mseg already has code to handle non-partial frees via the CAN_PARTLY_DESTROY define).
Credit for mmap emulation code goes to
http://www.genesys-e.de/jwalter/mix4win.htm
The Erlang patch / commit can be found here
http://github.com/bwhittle/otp/tree/win32_memfix
or fetched via
git fetch git://github.com/bwhittle/otp.git win32_memfix
In order to create a build with the memory fix do the following...
1) make clean
2) ./otp_build autoconf
3) ./otp_build configure
4) Manually edit erts/win32/config.h and append the following two lines
#define HAVE_MMAP 1
#define EMULATE_MMAP_WIN32 1
5) Then continue with the normal build process ./otp_build boot -a, etc
I left this part of the build manual as I'm unsure exactly where the defines should be placed (i.e. either standard windows defines in erl_win_sys.h, a change to the compiler params in the win32 makefile , or via a change to the configure script).
As for a test case I just used copy and pasted a simple line into the console.
V = <<0:829967295>>,V1 = <<1:829967295>>,V2 = <<2:829967295>>,V3 = <<3:829967295>>,V4 = <<4:829967295>>,V5 = <<5:829967295>>,V6 = <<6:829967295>>,V7 = <<7:829967295>>,V8 = <<8:829967295>>,V9 = <<9:829967295>>.
Without the fix, Erlang exits on my machine with an OOM error after executing the above line 3 times (at which point the Erlang process is only using 1.2 to 1.3gb of memory). With the fix, I'm able to run the line 10 or 11 times before failure (at which point the process is using around 2.4gb of memory).
Using other tests and smaller bit strings, I've been able to reach 2.8gb before running out of memory.
More information about the erlang-patches
mailing list