是否有可能在Java中强制进行垃圾收集,即使它很棘手?我知道System.gc();,Runtime.gc();但他们只建议做GC.我怎么强迫GC?
让我们假设,有一个Tree对象,具有根TreeNode对象,并且每个TreeNode都有leftNode和rightNode对象(例如BinaryTree对象)
如果我打电话:
myTree = null;
Run Code Online (Sandbox Code Playgroud)
树中相关的TreeNode对象真的会发生什么?将垃圾收集,或者我必须设置树对象内的所有相关对象?
我有一个Clojure程序在运行时消耗了大量的堆(我曾经在2.8GiB附近测量它),我正试图找到一种方法来减少其内存占用.我目前的计划是每隔一段时间强制进行垃圾收集,但我想知道这是不是一个好主意.我已经阅读了如何在Java中强制进行垃圾收集?并且我可以强制垃圾收集在Java中?并了解如何做 - 只是打电话(System/gc)- 但我不知道这是一个好主意,或者即使它是需要的.
这是程序的工作原理.我有大量遗留格式的文档,我正在尝试将其转换为HTML.遗留格式由几个XML文件组成:描述文档的元数据文件,并包含指向任意数量内容文件的链接(通常为一个,但也可以是几个 - 例如,某些文档具有"主要"内容和单独的脚注文件).对于最小的文档,转换需要几毫秒到最大文档的大约58秒.基本上,我正在写一个荣耀的XSLT处理器,但在一个多比XSLT更好的语言.
我刚刚开始在Clojure中编写的当前(相当天真)的方法构建了所有元数据文件的列表,然后执行以下操作:
(let [parsed-trees (map parse metadata-files)]
(dorun (map work-func parsed-trees)))
Run Code Online (Sandbox Code Playgroud)
work-func将文件转换为HTML并将结果写入磁盘,然后返回nil.(我试图丢弃每个文档的解析后的XML树,这在每次通过单个文档后非常大).我现在意识到虽然map是懒惰并且dorun抛弃了它迭代的序列的头部,但是我抓住seq头部的事实parsed-trees是我失败的原因.
我的新计划是将解析移动到work-func,以便它看起来像:
(defn work-func [metadata-filename]
(-> metadata-filename
e/parse
xml-to-html
write-html-file)
(System/gc))
Run Code Online (Sandbox Code Playgroud)
然后,我可以打电话work-func用map,或者可能pmap因为我有两个双核CPU,并希望每个文档处理后扔掉的大型XML树.
不过,我的问题是:经常告诉Java"请跟我清理"是一个好主意吗?或者我应该跳过(System/gc)调用work-func,让Java垃圾收集器在需要时运行?我的直觉是要保持调用,因为我知道(因为Java不能)在那时work-func,堆上会有大量数据可以摆脱,但我会欢迎输入来自更有经验的Java和/或Clojure程序员.