现在,我需要将大量数据从数据库加载到向量中,但是当我加载38000行数据时,程序会抛出OutOfMemoryError异常。 我该怎么做才能解决这个问题?
我认为我的程序中可能存在内存泄漏,检测它的好方法?谢谢
答案 0 :(得分:7)
为JVM提供更多内存(通常使用-Xmx
/ -Xms
)或不要将所有数据加载到内存中。
对于大量数据的许多操作,有些算法不需要同时访问所有数据。一类此类算法为divide and conquer algorithms。
答案 1 :(得分:3)
如果您必须拥有内存中的所有数据,请尝试缓存常见的对象。例如,如果您正在查看员工记录并且他们都有职位,请在加载数据时使用HashMap并重复使用已找到的职位。这可以大大降低您正在使用的内存量。
此外,在您执行任何操作之前,请使用分析器查看内存被浪费的位置,并检查可以进行垃圾回收的内容是否没有引用。同样,String是一个常见的例子,因为例如,如果您使用的是2000字符串的前10个字符,并且您使用了substring而不是分配新的String,那么您实际拥有的是对char的引用[2000数组,两个索引指向0和10.再次,一个巨大的内存浪费。
答案 2 :(得分:1)
您可以尝试增加堆大小:
java -Xms<initial heap size> -Xmx<maximum heap size>
默认为
java -Xms32m -Xmx128m
答案 3 :(得分:1)
你真的需要将这么大的对象存储在内存中吗?
根据您对该数据的处理方式,您可能希望将其拆分为较小的块。
答案 4 :(得分:1)
逐节加载数据。这不会让您同时处理所有数据,但您不必更改提供给JVM的内存。
答案 5 :(得分:1)
也许优化您的数据类?我见过一个案例,有人一直在使用Strings代替本机数据类型,比如int或double,因为每个类成员在内存中存储相对少量的数据对象时会产生OutOfMemoryError。看一看你没有复制你的对象。当然,增加堆大小:
java -Xmx512M(或您认为必要的任何内容)
答案 6 :(得分:1)
您可以使用分析器运行代码,以了解内存被占用的方式和原因。通过循环调试您的方式并观察正在实例化的内容。它们中有许多; JProfiler Java Memory Profiler,请参阅list of profilers here,依此类推。
答案 7 :(得分:0)
让您的程序使用更多内存或更好地重新考虑策略。你真的在内存中需要这么多数据吗?
答案 8 :(得分:0)
我知道你正试图将数据读入矢量 - 否则,如果你试图显示它们,我会建议你使用NatTable。它专为将大量数据读入表格而设计。
我相信它可能会在这里为另一位读者派上用场。
答案 9 :(得分:0)
使用内存映射文件。内存映射文件基本上可以根据需要增长,而无需访问堆。它确实需要您以解码友好的方式对数据进行编码。 (比如,为数据中的每一行保留固定大小是有意义的,以便快速跳过多行。)
Preon可让您轻松处理。它是一个框架,旨在对二进制编码数据做什么,Hibernate为关系数据库做了什么,而JAXB / XStream / XmlBeans用于XML。