使用 valgrind 对 C 检查内存时, OS X 上永远有内存泄露问题。
同样的代码放在 Linux 上完全没有问题。
.
如: int main(){
return 123;
}
.
valgrind 返回:
.
HEAP SUMMARY:
==4020== in use at exit: 22,146 bytes in 187 blocks
==4020== total heap usage: 271 allocs, 84 frees, 28,386 bytes allocated
==4020==
==4020== 2,064 bytes in 1 blocks are possibly lost in loss record 57 of 62
==4020== at 0x10000817C: malloczonemalloc (in/usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==4020== by 0x1004F3EFD: objccopyClassNamesForImage (in /usr/lib/libobjc.A.dylib)
==4020== by 0x1004E7182: protocols() (in /usr/lib/libobjc.A.dylib)
==4020== by 0x1004E7093: readClass(objc_class, bool, bool) (in /usr/lib/libobjc.A.dylib)
==4020== by 0x1004E4C13: gc_init (in /usr/lib/libobjc.A.dylib)
==4020== by 0x1004EC24E: objcinitializeClassPairinternal(objcclass, char const, objcclass, objc_class) (in /usr/lib/libobjc.A.dylib)
==4020== by 0x1004F9132: layoutstringcreate (in /usr/lib/libobjc.A.dylib)
==4020== by 0x1004E783C: realizeClass(objc_class) (in /usr/lib/libobjc.A.dylib)
==4020== by 0x1004E7300: copySwiftV1MangledName(char const, bool) (in /usr/lib/libobjc.A.dylib)
==4020== by 0x1004E72E9: copySwiftV1MangledName(char const, bool) (in /usr/lib/libobjc.A.dylib)
==4020== by 0x1004E72E9: copySwiftV1MangledName(char const, bool) (in /usr/lib/libobjc.A.dylib)
==4020== by 0x1004E72E9: copySwiftV1MangledName(char const, bool) (in /usr/lib/libobjc.A.dylib)
==4020==
==4020== LEAK SUMMARY:
==4020== definitely lost: 0 bytes in 0 blocks
==4020== indirectly lost: 0 bytes in 0 blocks
==4020== possibly lost: 2,064 bytes in 1 blocks
==4020== still reachable: 0 bytes in 0 blocks
==4020== suppressed: 20,082 bytes in 186 blocks
==4020==
==4020== For counts of detected and suppressed errors, rerun with: -v
==4020== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 17 from 17)
.
按照网上找的教程,将如下文件加入到 valgrind 的执行过程中。
.
{
Memcheck:Leak
match-leak-kinds: indirect
fun:malloc
fun:Balloc_D2A
fun:rvalloc_D2A
fun:dtoa
fun:vfprintf
fun:_v2printf
fun:vfprintf_l
fun:printf
fun:main
}
.
摘自: http://stackoverflow.com/questions/34573039/possible-memory-leak-valgrind-in-osx-el-capitan/35592274
.
只是屏蔽了内存泄露的具体信息,有没有什么方法,能从根本上解决?
.
装了 GCC 4.9,泄露依旧。
.
目的: No. allocs = No. frees
我看了你贴的SO的链接,按照那个链接的说法,valgrind的报告可能是错的。我倾向于同意这个意见。
另外,如果假设libobjc真的有问题,你自己肯定改不了,你可以去跟苹果报告bug,但是valgrind的报告是不是足够证明libobjc有问题,我存疑,我建议你能验证确有问题再说。例如用Xcode里面的instrument可以检测到问题再说。
再说另外一句,追求性能和内存占用少,也是要有轻重的。为啥说调性能之前必须有profile呢,就是在于此,永远都是抓大放小。如果真有2,064字节,而且是只泄漏一次的,根本不需要去解决。
最常见的问题点是在一个守护进程,服务器循环里面,有一个周期性泄漏,这种才是问题,哪怕一次一个字节,都值得注意。
做性能调优,不是强迫症该做的事情,而是工程师该做的事情(实践为先)。
https://bugs.kde.org/show_bug.cgi?id=343663 有人报过。不一定是你的问题,不过从有这种历史看起来,很大概率不是 OSX 的问题,是 valgrind 误报。valgrind 主要是 Linux 用,OSX 很可能会有假阳性