w***g 发帖数: 5958 | 1 有人遇到过这个问题吗?这事情搞了我整整两天,一直以为是内存泄漏。
结果发现是glibc的问题-- 这个thread释放的内存那个thread没法用。
这次大涨见识了。 |
k**********g 发帖数: 989 | 2
http://stackoverflow.com/questions/855763/is-malloc-thread-safe
Mostly related to the NO_THREADS define. It could be a hassle to search for
defines in large libraries especially when there are dependencies on third-
party libraries.
Microsoft MSVCRT also has "single threaded version" and "multi-threaded
version".
Basically, there's no reason to use the single-threaded version C runtime
nowadays.
【在 w***g 的大作中提到】 : 有人遇到过这个问题吗?这事情搞了我整整两天,一直以为是内存泄漏。 : 结果发现是glibc的问题-- 这个thread释放的内存那个thread没法用。 : 这次大涨见识了。
|
T********i 发帖数: 2416 | 3 你为什么以为是内存泄漏呢?
【在 w***g 的大作中提到】 : 有人遇到过这个问题吗?这事情搞了我整整两天,一直以为是内存泄漏。 : 结果发现是glibc的问题-- 这个thread释放的内存那个thread没法用。 : 这次大涨见识了。
|
w***g 发帖数: 5958 | 4 服务器需要长期运行,运行过程中动态加载新的模型。每个模型非常大(N多G)。
本来加载-释放-加载-释放...不应该导致内存增长。
问题是这些加载释放的请求被不同的线程响应了,glibc的行为导致
不同线程间空闲内存无法复用。理论上说每个线程都浪费一份模型大小
的内存才能保证malloc开始复用内存。然后我有好几十个线程。
于是就发现内存一直涨一直涨,一涨就是十好几G。看起来跟内存泄漏
非常像。
【在 T********i 的大作中提到】 : 你为什么以为是内存泄漏呢?
|
T********i 发帖数: 2416 | 5 反正对性能也没有影响。多占用一点address spaces而已。10几个G也是小意思了。现
在一台服务器不消耗上百G都不好意思跟人打招呼。
【在 w***g 的大作中提到】 : 服务器需要长期运行,运行过程中动态加载新的模型。每个模型非常大(N多G)。 : 本来加载-释放-加载-释放...不应该导致内存增长。 : 问题是这些加载释放的请求被不同的线程响应了,glibc的行为导致 : 不同线程间空闲内存无法复用。理论上说每个线程都浪费一份模型大小 : 的内存才能保证malloc开始复用内存。然后我有好几十个线程。 : 于是就发现内存一直涨一直涨,一涨就是十好几G。看起来跟内存泄漏 : 非常像。
|
w***g 发帖数: 5958 | 6 之前确实一直对性能没有影响,偶尔重启都被HA给掩盖过去了,
也没有注意。最近数据突然增多了才发现的问题。
【在 T********i 的大作中提到】 : 反正对性能也没有影响。多占用一点address spaces而已。10几个G也是小意思了。现 : 在一台服务器不消耗上百G都不好意思跟人打招呼。
|
T********i 发帖数: 2416 | 7 顶多每次动态加载一部分内存swap到硬盘。对性能影响大么?
【在 w***g 的大作中提到】 : 之前确实一直对性能没有影响,偶尔重启都被HA给掩盖过去了, : 也没有注意。最近数据突然增多了才发现的问题。
|
w***g 发帖数: 5958 | 8 malloc问系统要的内存是不退回去的。假设我每次加载20G,
有50个线程,最多会分配50*20G = 1T。所以最后会内存分配
失败抛出异常。远在这之前swap会开始干活,本来这也没事,
死就死在不知道哪儿有个锁,所以swap起来系统就停止响应了。
应该是log和swap在一个物理盘上。log写不进去了。
【在 T********i 的大作中提到】 : 顶多每次动态加载一部分内存swap到硬盘。对性能影响大么?
|
h*i 发帖数: 3446 | 9 goodbug同学会说“为什么不用Java?”, 而我会同意他。
【在 w***g 的大作中提到】 : 有人遇到过这个问题吗?这事情搞了我整整两天,一直以为是内存泄漏。 : 结果发现是glibc的问题-- 这个thread释放的内存那个thread没法用。 : 这次大涨见识了。
|
T********i 发帖数: 2416 | 10 你这种大量计算的问题,50个线程太多了。
线程数量应该比实际的处理器数量少才对。
你能不能试试把计算任务串行化?
【在 w***g 的大作中提到】 : malloc问系统要的内存是不退回去的。假设我每次加载20G, : 有50个线程,最多会分配50*20G = 1T。所以最后会内存分配 : 失败抛出异常。远在这之前swap会开始干活,本来这也没事, : 死就死在不知道哪儿有个锁,所以swap起来系统就停止响应了。 : 应该是log和swap在一个物理盘上。log写不进去了。
|
|
|
w***g 发帖数: 5958 | 11 因为是网络服务,还要从数据库读东西,中间延时比较多。
每个请求真正的CPU时间往往远不足1ms。所以需要多线程。
楼上说java也有道理。不过我这个应用如果用java实现,
再多5倍机器都不够。我这个问题在java里可能就成为正常情况了,
反正是多耗内存的事情。有人能确认jvm没有用pthread和malloc吗?
C++是我的job security。
【在 T********i 的大作中提到】 : 你这种大量计算的问题,50个线程太多了。 : 线程数量应该比实际的处理器数量少才对。 : 你能不能试试把计算任务串行化?
|
T********i 发帖数: 2416 | 12 你试过tcmalloc没有?貌似能解决你的问题。
【在 w***g 的大作中提到】 : 因为是网络服务,还要从数据库读东西,中间延时比较多。 : 每个请求真正的CPU时间往往远不足1ms。所以需要多线程。 : 楼上说java也有道理。不过我这个应用如果用java实现, : 再多5倍机器都不够。我这个问题在java里可能就成为正常情况了, : 反正是多耗内存的事情。有人能确认jvm没有用pthread和malloc吗? : C++是我的job security。
|
w***g 发帖数: 5958 | 13 话说如果我没发现原因的话是打算试各种xxmalloc了。
我那台机器版本太老,用来debug malloc那些函数都用的int32,全都overflow。
发现以后三分钟就fix了。起了一个线程专门负责分配内存就解决了。
我怀疑我那个系统要上tcmalloc的话还能有不少性能提高。不过我还没到那一步,
tcmalloc目前还是保留trick。
【在 T********i 的大作中提到】 : 你试过tcmalloc没有?貌似能解决你的问题。
|
p*u 发帖数: 2454 | 14
how can u scale w/ such design?
【在 w***g 的大作中提到】 : 因为是网络服务,还要从数据库读东西,中间延时比较多。 : 每个请求真正的CPU时间往往远不足1ms。所以需要多线程。 : 楼上说java也有道理。不过我这个应用如果用java实现, : 再多5倍机器都不够。我这个问题在java里可能就成为正常情况了, : 反正是多耗内存的事情。有人能确认jvm没有用pthread和malloc吗? : C++是我的job security。
|
w***x 发帖数: 105 | 15 check this: http://goog-perftools.sourceforge.net/doc/tcmalloc.html
一般的alloctor都会做些hold工作,记得mallocopt可以控制一些hold的上限,可以试
试。
另外大内存完全可以自己mmap,省得malloc再插一脚。 |
w***g 发帖数: 5958 | 16 昨天那个fix只在我的ubuntu上干活,回了生产系统的centos 5.x还是一个劲地长。
然后上tcmalloc,世界一下子清净了。以后在有啥需要分配大量零散内存的程序,
肯定无脑直接tcmalloc了。
有句话叫什么来着,不到黄河心不死。
【在 w***x 的大作中提到】 : check this: http://goog-perftools.sourceforge.net/doc/tcmalloc.html : 一般的alloctor都会做些hold工作,记得mallocopt可以控制一些hold的上限,可以试 : 试。 : 另外大内存完全可以自己mmap,省得malloc再插一脚。
|