将discard-document与saxon和xquery一起使用

时间:2015-12-29 16:15:41

标签: xquery saxon

我正在尝试找一个关于如何使用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

替换所有声明

由于

2 个答案:

答案 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对内存消耗没有影响,那可能是因为还有其他东西仍在引用文档 - 例如,全局变量。