2016-10-20 2 views
4

~ 2000 개의 XML 문서를 구문 분석하고, 각 문서에서 특정 노드를 추출하여 단일 문서에 추가하고 저장해야합니다. XPath를 사용할 수 있도록 내부 C 노드를 사용하고 있습니다. 문제는 내가 문서에서 반복 할 때 메모리에서 내부 C 객체를 제거 할 수 없어 사용 된 메모리가> 4GB를 초과한다는 것입니다. 그 문제는로드 된 트리 (각 문서의 해시 트리를로드하고 삭제하는 루프를 실행)가 아니라 필터링 된 노드 또는 루트 노드를 사용하여 문제가 발생한다는 것을 알고 있습니다.R XML - 메모리에서 내부 C 노드를 제거 할 수 없습니다.

다음은 현재 사용중인 코드입니다. 각 반복 끝에 메모리를 지울 수 있도록 내가 놓친 것은 무엇입니까?

xmlDoc <- xmlHashTree() 
rootNode <- newXMLNode("root") 

for (i in seq_along(all.docs)){ 

    # Read in the doc, filter out nodes, remove temp doc 
    temp.xml <- xmlParse(all.docs[i]) 
    filteredNodes <- newXMLNode(all.docs[i], 
        xpathApply(temp.xml,"//my.node[@my.attr='my.value'")) 
    free(temp.xml) 
    rm(temp.xml) 

    # Add filtered nodes to root node and get rid of them. 
    addChildren(rootNode, filteredNodes) 
    removeNodes(filteredNodes, free = TRUE) 
    rm(filteredNodes) 

} 
# Add root node to doc and save that new log. 
xmlDoc <- addChildren(root) 
saveXML(xmlDoc, "MergedDocs.xml") 

그래서 내가 메모리 누수없이 'XML'및 처리에 많은 시간을 사용 할 수있는 방법을 발견 한 당신의 도움이

+0

당신이 어딘가에서'GC를()'추가 또는 전환을 시도 할 수도없는()'그래서 당신은 이미'사용하고 'xml2' 패키지 (당신이하는 모든 것을 지원하는지 확신 할 수는 없지만, 어떤 것들은 더 나은 메모리 관리를합니다). – hrbrmstr

+0

고마워요,하지만 그럴 수는 없어요. 루프 외부에서'gc() '를 실행한다고해서 메모리가 지워지지는 않습니다. –

+0

IIRC에서'XML' 패키지는 피할 수없는 메모리 누수를 알고 있습니다. 대신 ['xml2'] (https://cran.r-project.org/web/packages/xml2/index.html)을 보시기 바랍니다. –

답변

1

주셔서 감사합니다. 운 좋게도 'xml2'는 문서와 노드를 생성 할 수 있습니다. 완전성을 위해 'xml2'를 사용하는 솔루션이 있습니다. 사람이, 'XML'을 사용하여 방법을 알고있는 경우의 차임 않습니다.

xmlDoc <- xml_new_document() %>% xml_add_child("root") 

for (i in seq_along(all.docs)){ 
# Read in the log. 
rawXML <- read_xml(all.docs[i]) 

# Filter relevant nodes and cast them to a list of children. 
tempNodes <- xml_find_all(rawXML, "//my.node[@my.attr='my.value'") 
theChildren <- xml_children(tempNodes) 

# Get rid of the temp doc. 
rm(rawXML) 

# Add the filtered nodes to the log under a node named after the file name 
xmlDoc %>% 
    xml_add_child(all.docs[i] %>% 
    xml_add_child(theChildren[[1]]) %>% 
    invisible() 

# Remove the temp objects 
rm(tempNodes); rm(theChildren) 
} 
관련 문제