我正在使用libxml2编写XML解析器。实际上,我完成了它,但有一个非常讨厌的内存问题。该程序首先从我的数据库中获取一些链接,所有这些链接指向XML文件。我用curl下载它们。这个过程很简单:我下载一个文件,然后解析它,依此类推......
问题似乎是在解析完成时。 Curl下载下一个文件,但似乎没有释放以前的XML,因为我猜libxml2将它加载到RAM中。在解析最后一个XML时,我发现自己有一个~2.6GB的泄漏(是的,其中一些文件非常大......)我的机器只有4GB的RAM。它目前有效,但将来会有更多链接添加到数据库中,所以我现在必须修复它。
我的代码很基本:
xmlDocPtr doc;
doc = xmlParseFile("data.xml");
/* code to parse the file... */
xmlFreeDoc(doc);
我尝试使用:
xmlCleanupParser();
但文档说:“它不会释放任何与文档相关的内存。” (http://xmlsoft.org/html/libxml-parser.html#xmlCleanupParser)
所以,我的问题是:有人知道如何释放所有这些文件相关的内存吗?
答案 0 :(得分:6)
问题是你正在以错误的方式查看统计数据......
当程序启动时,它会从操作系统中为堆分配一些内存。当它执行malloc
(或类似函数)时,C运行时从该堆中获取切片,直到它用完为止。之后,它会自动向OS请求更多内存,也许每次都在更大的块中。当程序执行free
时,它会将释放的内存标记为可用于进一步的malloc
,但将将内存返回给操作系统。
您可能认为这种行为是错误的,程序正在泄漏,但事实并非如此:释放的内存被考虑在内,而不是在操作系统中,而是在应用程序的C库层中。证据就是第二个XML文件的内存不会添加到第一个文件中:只有当它是最好的文件时才会显而易见。
您可能还认为,如果此程序不再使用此内存,则只会浪费在此处,并且不能用于其他进程。但事实并非如此:如果内存在一段时间内没有被触及而在其他地方需要,那么OS虚拟内存管理器会将其交换出来并重新使用它。
所以,我的猜测是,实际上你没有问题。
PS:我刚刚描述的并不总是如此。特别是许多C库区分小内存块和大内存块并以不同方式分配它们。答案 1 :(得分:1)
游戏后期但今天刚发现这篇文章。它也可能对其他读者有用。
如果要解析或生成大型文档,可以考虑使用XmlReader和XmlReader API。无论输入多大,都会大幅减少内存使用量,实际上几乎是一直使用。
http://xmlsoft.org/html/libxml-xmlreader.html http://xmlsoft.org/html/libxml-xmlwriter.html