TCMalloc and MySQL
github.com
github.com
"TCMalloc currently does not return any memory to the system."[1]
That means if you have many long-running processes, then each of them will consume the maximum amount of memory that it ever has. Not good for a multi-tenant setup.
If it's a dedicated server running one multi-threaded application, maybe that's OK, although I'd be a little bit wary anyway.
I should note that, even if the application doesn't let the memory go, the OS could page out the inactive regions. Not really something that I would like to rely on, though. There are some other caveats also, like it would make memory accounting a little trickier ("Wow, that process is huge! Oh, never mind, it's mostly paged out.").
For what it's worth, I just spent considerable effort to get rid of tcmalloc due (in part) to problems like this. [2]
[1] http://goog-perftools.sourceforge.net/doc/tcmalloc.html
[2] You wouldn't think it would be a lot of effort, but we were using dynamic libraries that were linking against tcmalloc, which is outright dangerous if the main executable isn't linked against tcmalloc (you don't want to replace the allocator in a running executable). And some of those libraries were actually using the tcmalloc-specific features/symbols, so I had to get away from that first.
edit: apparently tcmalloc is using mmap to allocate more of its memory than i realized, not sure why i thought it was using sbrk for everything
http://en.wikipedia.org/wiki/C_dynamic_memory_allocation#Ope...
Pages that are mapped but are left untouched for a long time aren't problematic in modern systems. There is a small cost for the PTE but nothting like an entire page of physical memory.
The OS can either keep it resident or swap it out, but it has no way of knowing that it is no longer in use (short of something like madvise()). In the realm of sanity, the OS can't just arbitrarily throw away memory that a process has written to (unless it also kills the process).
https://code.google.com/p/gperftools/source/browse/trunk/src...
One caveat: physical memory and swap space is released, but the process's virtual size will not decrease since tcmalloc uses madvise(MNONE) to release memory.
About [2], code using tcmalloc-specific features/symbols is definitely a problem. I would strongly advise against doing that and sticking to the libc interfaces instead for the reason you pointed out.
Yeah, regarding [2], that was definitely not my idea.
I say this as someone who has implemented a lock-free memory allocator for mutlithreaded applications. I cared about performance, and I was willing to sacrifice nice things like detecting double-frees. I moved away from the project largely because I didn't want to be in a performance race with TCMalloc. (At the end, TCMalloc outperformed my allocator in some benchmarks, but not in others. But, surprisingly, there were also some places were glibc outperformed both.)
It's probably also used in all Xbox-es too...
Good benchmark showing the impact of the different options:
http://www.mysqlperformanceblog.com/2012/07/05/impact-of-mem...
http://i.imgur.com/4RzmQD6.png
Looks like those on centos can install it easily via
yum install gperftools-libs --enablerepo=epel
which installs /usr/lib64/libtcmalloc.so.4
/usr/lib64/libtcmalloc_minimal.so.4
then you just need to edit your mysql init script? test -e /usr/lib64/libtcmalloc_minimal.so.4 && export LD_PRELOAD="/usr/lib64/libtcmalloc_minimal.so.4"
You can also try jemalloc which supposedly is close to as good as tcmalloc but uses less memory yum install jemalloc --enablerepo=epel
which installs /usr/lib64/libjemalloc.so.1
and for your init.d test -e /usr/lib64/libjemalloc.so.1 && export LD_PRELOAD="/usr/lib64/libjemalloc.so.1" [mysqld_safe]
malloc-lib=/usr/lib64/libtcmalloc_minimal.so.4
or malloc-lib=/usr/lib64/libjemalloc.so.1
http://dev.mysql.com/doc/refman/5.5/en//mysqld-safe.html#opt...no export or script editing required
We have been using tcmalloc for a while on our databases, as well as disabling the transparent huge pages and transparent huge page defrag (centos6). It made a big difference for us.
Because it's an external environment variable, it doesn't actually show inside any of mysql's settings. No startup errors or runtime problems is always nice but I really am curious to know for a fact it worked.
Will probably have to ask this on stackexchange if you don't know.
# as root or sudo
pmap -x $(pidof mysqld)|grep mallochttp://www.mysqlperformanceblog.com/2012/07/05/impact-of-mem...
http://www.quora.com/Is-tcmalloc-stable-enough-for-productio...
The author of nedmalloc is working on a very exciting C++ API (actually, I think it's API-complete now) to make it a drop-in STL allocator. I personally use the C API in my C++ applications without a problem, mainly as a pool allocator. For me, the Windows allocators (both the old default and the new "low-fragmentation" default) are absolutely abysmal at deallocation. Pool allocators in general make that go away.
Strikes me as a perfect example of a culture that works hard and enjoys the hell out of it too.