malloc内核恐慌,而不是返回NULL

时间:2016-12-14 07:25:20

标签: memory

我正在尝试从"Expert C Programming"进行练习,其中重点是查看程序可以分配多少内存。当malloc无法再分配NULL时,它取决于#include <stdio.h> #include <stdlib.h> int main() { int totalMB = 0; int oneMeg = 1<<20; while (malloc(oneMeg)) { ++totalMB; } printf("Allocated %d Mb total \n", totalMB); return 0; }

Anonymous UUID:       0B87CC9D-2495-4639-EA18-6F1F8696029F

Tue Dec 13 23:09:12 2016

*** Panic Report ***
panic(cpu 0 caller 0xffffff800c51f5a4): "zalloc: zone map exhausted while allocating from zone VM map entries, likely due to memory leak in zone VM map entries (6178859600 total bytes, 77235745 elements allocated)"@/Library/Caches/com.apple.xbs/Sources/xnu/xnu-3248.50.21/osfmk/kern/zalloc.c:2628
Backtrace (CPU 0), Frame : Return Address
0xffffff91f89bb960 : 0xffffff800c4dab12 
0xffffff91f89bb9e0 : 0xffffff800c51f5a4 
0xffffff91f89bbb10 : 0xffffff800c5614e0 
0xffffff91f89bbb30 : 0xffffff800c5550e2 
0xffffff91f89bbba0 : 0xffffff800c554960 
0xffffff91f89bbd90 : 0xffffff800c55f493 
0xffffff91f89bbea0 : 0xffffff800c4d17cb 
0xffffff91f89bbf10 : 0xffffff800c5b8dca 
0xffffff91f89bbfb0 : 0xffffff800c5ecc86 

BSD process name corresponding to current thread: a.out

Mac OS version:
15F34

在我的16GB Macbook Pro上分配~8GB后,我得到内核恐慌,而不是打印总数。

内核恐慌日志:

malloc

我明白这可以很容易地通过医生的陈词滥调来解决:“当你这样做会有伤害吗?那就不要这样做了”但我想理解为什么public static void sesame2virtuoso(String server, String repo, String graphName) throws IOException, RepositoryException { //connect sesame HTTPRepository repository = new HTTPRepository(server, repo); repository.setUsernameAndPassword(PropertiesUtil.PropValues("user"), PropertiesUtil.PropValues("password")); repository.initialize(); RepositoryConnection connection = repository.getConnection(); ValueFactory factory = connection.getValueFactory(); try { RepositoryResult<Statement> statements = connection.getStatements(null, null, null, false); Statement statement; String sub, pre, obj; VirtGraph graph = new VirtGraph(graphName, URL, "dba", "dba"); int count = 0; while (statements.hasNext()) { statement = statements.next(); sub = statement.getSubject().stringValue(); pre = statement.getPredicate().stringValue(); obj = statement.getObject().stringValue(); Node sub1 = Node.createURI(sub); Node pre1 = Node.createURI(pre); Node obj1 = Node.createURI(obj); try { graph.add(new Triple(sub1, pre1, obj1)); } catch (Exception e) { continue; } } } catch (Exception e) { e.printStackTrace(); } } 没有按预期工作。< / p>

OS X 10.11.5

1 个答案:

答案 0 :(得分:2)

对于该问题的最终答案,您可以查看源代码,您可以在此处找到:

zalloc.c source in XNU

在该源文件中找到函数zalloc_internal()。这是给内核恐慌的函数。

在该功能中,您将找到一个&#34; for(;;){&#34;循环,它基本上尝试分配您在指定区域中请求的内存。如果没有足够的空间,它会立即再次尝试。如果失败,它会执行zone_gc()(垃圾收集)以尝试回收内存。如果这也失败了,它只会内核恐慌 - 有效地停止计算机。

如果您想了解zalloc.c的工作原理,请查找基于区域的内存分配器。

您的程序正在使内核在名为&#34; VM映射条目&#34;的区域中空间不足,这是在引导时分配的预定义区域。如果你一次分配超过1 MB,你可能会得到你期望从你的程序得到的结果,没有内核恐慌。

本质上,内核分配几千兆字节的内存并不是一个问题。但是,分配总计达到这些千兆字节的数千个较小的分配要困难得多。