我正在尝试找一个关于如何使用Saxon的discard-document功能的例子。我有大约50个文件,每个40mb,所以他们在我的xquery脚本中使用大约4.5GB的内存。
我在每次调用XML文件后都尝试使用saxon:discard-document(doc("filename.xml"))
,但这可能不是正确的方法吗?使用它后,内存使用量没有差异。
我还发现了一些关于它的使用的问题(7年前),他们建议使用discard-document运行xpath。但是我对该文档有很多调用,所以我必须用saxon:discard-document(doc("filename.xml"))/xpath/etc/etc/etc
由于
答案 0 :(得分:2)
我认为这是一个很好的问题,而且没有太多可用信息,所以我会尝试自己回答。
以下是有关如何使用撒克逊的示例:discard-document:
declare function local:doStuffInDocument($doc as document-node()) {
$doc//testPath
};
let $urls := ("http://url1", "http://url2")
let $results :=
for $url in $urls
let $doc := saxon:discard-document(doc($url))
return local:doStuffInDocument($doc)
return $results
通过使用类似的代码,我设法将内存消耗从4 + GB减少到仅300MB。
要了解丢弃文件的作用,以下是来自SF maillist的Michael Kay发表的精彩评论:
只是解释discard-document()的作用:
Saxon维护(由变压器/控制器拥有)一张表 将文档URI映射到文档节点。当你调用文档() 函数,Saxon查看URI是否在此表中,如果是 是,它返回相应的文档节点。如果不是,它会读取 并解析在该URI找到的资源。的效果 saxon:discard-document()是从中删除文档的条目 这个映射表。 (当然,如果从中引用文档 表然后垃圾收集器将文件保存在内存中;如果 它没有从表中引用然后它符合条件 垃圾收集。如果它被引用,它将不会被垃圾收集 来自全局变量;但它仍将缺席 另一次调用document()的事件再次使用相同的URI。)
迈克尔凯的另一个人在Altova发现maillist:
在Saxon中,如果使用doc()或document()函数,则使用该文件 将被加载到内存中,并将留在内存中直到结束 运行,以防它再次被引用。所以你会达到同样的目标 与一个大文件一样的大量小文件的内存问题 - 更糟糕的是,事实上,因为每个文档的开销很大。
但是,有一种解决方法:扩展功能 saxon:discard-document()导致文档被丢弃 一旦没有垃圾收集器就会被内存收集 引用它。
答案 1 :(得分:1)
理解封面下实际发生的事情可能很有用。 url(r'^voteuppost$', VoteUpPost.as_view()),
函数在缓存中查找文档是否已存在;如果没有,它会读取文档,将其添加到缓存中,然后返回它。 doc()
函数查看文档是否在缓存中,如果是,则将其删除,然后返回它。通过从缓存中删除文档,可以在不再引用文档时使其符合垃圾回收的条件。如果使用discard-document对内存消耗没有影响,那可能是因为还有其他东西仍在引用文档 - 例如,全局变量。