我有一个适用于CSV文件的swing应用程序。它逐行读取完整文件,计算一些必需的统计信息并显示输出。 输出屏幕的上半部分以JTable中的顺序显示文件中的每条记录,而下半部分显示基于该数据计算的统计数据。问题是JVM占用的内存是文件大小的4倍。 (处理86MB文件堆区域时使用377 MB空间 - 使用jVisualVM检查内存利用率。)
注意:
我已经使用LineNumberReader来读取文件(因为有特殊要求,如果有助于内存使用,我可以更改它)
为了读取每一行,使用readLine(),然后为该记录的各个字段调用该行的字符串.split(',')。
存储在Vector中的每条记录都显示在JTable中,而其他统计信息存储在JavaBean类的HashMap,TreeMap和摘要数据中。还使用JFreeChart绘制了一个图表。
请建议降低内存利用率,因为我需要处理2GB文件。
答案 0 :(得分:1)
尝试给OpenCSV一个镜头。它只在您使用readNext()方法时存储最后一行读取行。对于大文件,这是完美的。
在他们的网站上,以下是他们支持的功能:
每行任意数量的值
忽略引用元素中的逗号
使用嵌入式回车符(即条目)处理带引号的条目 跨越多行)
可配置的分隔符和引号字符(或使用合理的 缺省值)
一次阅读所有条目,或使用Iterator样式模型
从String []创建csv文件(即自动转义嵌入式文件) 引用字符)
答案 1 :(得分:0)
使用最佳做法升级程序
答案 2 :(得分:0)
每个Java对象都有a memory overhead,所以如果你的字符串很短,这可以解释为什么你的文件大小是你的4倍。您还必须计算Vector的大小及其内部结构。我认为Map
不会提高内存使用率,因为Java Strings已尽可能尝试在内存中指向相同的地址。
我认为你应该修改你的设计。鉴于您的要求
输出屏幕的上半部分显示文件中的每条记录 在JTable中排序,而下半部分显示基于的计算统计 那个数据
您不需要将整个文件存储在内存中。您需要完全读取来计算统计信息,这当然可以使用非常少量的内存来完成。关于JTable部分,这可以通过多种方式实现,而需要2GB的堆空间用于您的程序!当有人想在内存中保留CSV时,我认为一定有问题! Apache IO LineIterator
答案 3 :(得分:0)
增加JVM堆大小(-Xms和-Xmx)。如果你有记忆,这是最好的解决方案。如果你不能这样做,你将需要找到一个折衷方案,它将是数据模型和表示(GUI)更改的组合,通常会导致代码复杂性增加和出现错误。