我正在研究一个不断处理千兆字节数据的程序,主要是基元和字符串。我需要避免通过自动装箱将原语转换为对象,因为这会爆炸堆大小和GC时间。
目前,我在VisualVM中进行更改并运行代码,看看我有数百万个额外的整数或短片或对象。然后我将调试器中的代码单步执行到我的库和JDK类中,以找到装箱发生的位置。有工具来帮助解决这个问题吗?
我使用Intellij作为我的IDE。在Intellij中,您可以使用检查在您自己的代码中查找自动装箱,但它似乎不会扩展到库代码。为此,请从菜单中选择:
Analyzye>>按名称运行检查...
然后输入' auto'在提示。应出现自动装箱检查以供选择。
然而,此时, 我已从我自己的代码中删除了基本上所有的自动装箱。我需要的是能够找出当我将原语传递给库方法时,库代码是否在任何时候自动装箱原语。
答案 0 :(得分:1)
您应该通过代码查看对Integer,Double等的任何引用...应该可以使用Eclipse或IntelliJ轻松完成。你是否可以在Javas build in Maps,Collections等中保存大量数据,原始类型的包装器由于泛型而自动装箱?
摆脱这种情况的一个好方法是使用GNU Trove而不是内置数据结构的javas:http://trove4j.sourceforge.net/html/overview.html。 In提供使用基本类型而不是泛型的地图和集合,并减少内存使用。
创建大量对象实例的另一个罪魁祸首可能是使用InvocationHandler接口。每次调用方法时,这都会为方法的参数创建一个Objects数组。代理对象经常使用它。您是否有第三方库或拥有这样做的代码?
最后,使用可以分层显示对象实例的分析器。我认为VisualVM做到了这一点,不确定。
你不应该像某些人所建议的那样诉诸C ++。你可以围绕它进行设计。
答案 1 :(得分:1)
应该可以编写一个为valueOf调用添加日志记录的简单javaagent(Integer.valueOf)此任务所需的只是字节码操作库,如Javassist
答案 2 :(得分:0)
假设您拥有所使用的库的来源,那么使用Structural Search&更换?使用结构搜索&中的Copy existing template...
按钮。替换对话框并选择boxed expressions
。这将找到表达式(未明确)加框的所有位置。
在范围Project and Libraries
中搜索以搜索所有位置或创建自定义范围,例如lib:omg.a.package..*
之类的模式,仅在该包中搜索。