aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/memory.cpp
AgeCommit message (Collapse)AuthorFilesLines
2017-03-06roll back to the old mallinfo() implementation of memory limiting on Linux ↵Robin Haberkorn1-60/+114
and added a FreeBSD/jemalloc-specific implementation * largely reverts 39cfc573, but leaves in minor and documentation changes. * further experimentation of memory limiting using malloc() wrapping has shown additional problems, like dlsym() calling malloc-functions, further reducing the implementation to glibc-specific means. This means there had been no implementation for FreeBSD and checks would have to rely on undocumented internal implementation details of different libcs, which is not a good thing. * Other problems have been identified, like having to wrap calloc(), guarding against underruns and multi-thread safety had been identified but could be worked around. * A technique by calculating the memory usage as sbrk(0) - &end has been shown to be effective enough, at least on glibc. However even on glibc it has shortcomings since malloc() will somtimes use mmap() for allocations and the technique relies on implementation details of the libc. Furthermore another malloc_trim(0) had to be added to the error recovery in interactive mode, since glibc does not adjust the program break automatically (to avoid syscalls I presume). * On FreeBSD/jemalloc, the sbrk(0) method totally fails because jemalloc exclusively allocates via mmap() -> that solution was discarded as well. * Since all evaluated techniques turn out to be highly platform specific, I reverted to the simple and stable platform-specific mallinfo() API on Linux. * On FreeBSD/jemalloc, it's possible to use mallctl("stats.allocated") for the same purpose - so it works there, too now. It's slower than the other techniques, though. * A lengthy discussion has been added to memory.cpp, so that we do not repeat the previous mistakes.
2017-03-05memory limiting: libc malloc() and realloc() can return NULLRobin Haberkorn1-2/+4
* shouldn't make much of a difference, since we're in deep trouble when they return NULL, but the wrappers should be transparent instead of crashing in malloc_usable_size().
2017-03-05replaced Linux-specific mallinfo()-based memory limiting with a more ↵Robin Haberkorn1-17/+90
portable and faster hack * Works by "hooking" into malloc() and friends and counting the usable heap object sizes with malloc_usable_size(). Thus, it has no memory-overhead. * Will work at least on Linux and (Free)BSD. Other UNIXoid systems may work as well - this is tested by ./configure. * Usually faster than even the fallback implementation since the memory limit is hit earlier. * A similar approach could be tried on Windows (TODO). * A proper memory-limiting counting all malloc()s in the system can make a huge difference as this test case shows: sciteco -e '<@EU[X^E\a]"^E\a"%a>' It will allocate gigabytes before hitting the 500MB memory limit... * Fixed the UNIX-function checks on BSDs.
2017-03-03updated copyright to 2017Robin Haberkorn1-1/+1
2016-11-22partially reversed/fixed-up b7ff56db631: avoid g_slice allocators and ↵Robin Haberkorn1-14/+22
performance issues with memory measurements * Fixed build problems on Windows * g_slice on Windows has been shown to be of little use either and it does not work well with the GetProcessMemoryInfo() measurements. Also, it brings the same problem as on Glibc: Not even command-line termination returns the memory to the OS. Therefore, we don't use g_slice at all and commented on it. * The custom Linux and Windows memory measurement approaches have been shown to be inefficient. As a workaround, scripts disable memory limiting. * A better approach -- but it will only work on Glibc -- might be to hook into malloc(), realloc() and free() globally and use the malloc_usable_size() of a heap object for memory measurements. This will be relatively precise and cheap. * We still need the "Object" base class in order to measure memory usage as a fallback approach.
2016-11-20fixed glib warnings about using g_mem_set_vtable() and revised memory limitingRobin Haberkorn1-0/+168
* we were basing the glib allocators on throwing std::bad_alloc just like the C++ operators. However, this always was unsafe since we were throwing exceptions across plain-C frames (Glib). Also, the memory vtable has been deprecated in Glib, resulting in ugly warnings. * Instead, we now let the C++ new/delete operators work like Glib by basing them on g_malloc/g_slice. This means they will assert and the application will terminate abnormally in case of OOM. OOMs cannot be handled properly anyway, so it is more important to have a good memory limiting mechanism. * Memory limiting has been completely revised. Instead of approximating undo stack sizes using virtual methods (which is unprecise and comes with a performance penalty), we now use a common base class SciTECO::Object to count the memory required by all objects allocated within SciTECO. This is less precise than using global replacement new/deletes which would allow us to control allocations in all C++ code including Scintilla, but they are only supported as of C++14 (GCC 5) and adding compile-time checks would be cumbersome. In any case, we're missing Glib allocations (esp. strings). * As a platform-specific extension, on Linux/glibc we use mallinfo() to count the exact memory usage of the process. On Windows, we use GetProcessMemoryInfo() -- the latter implementation is currently UNTESTED. * We use g_malloc() for new/delete operators when there is malloc_trim() since g_slice does not free heap chunks properly (probably does its own mmap()ing), rendering malloc_trim() ineffective. We've also benchmarked g_slice on Linux/glib (malloc_trim() shouldn't be available elsewhere) and found that it brings no significant performance benefit. On all other platforms, we use g_slice since it is assumed that it at least does not hurt. The new g_slice based allocators should be tested on MSVCRT since I assume that they bring a significant performance benefit on Windows. * Memory limiting does now work in batch mode as well and is still enabled by default. * The old UndoTokenWithSize CRTP hack could be removed. UndoStack operations should be a bit faster now. But on the other hand, there will be an overhead due to repeated memory limit checking on every processed character.