2009-08-12 77 views
1

现在,我需要从数据库加载大量数据到一个向量中,但是当我加载38000行数据时,程序抛出OutOfMemoryError异常。 我能做些什么来处理这个问题?如何处理java中的大量数据

我觉得有可能是我的一些程序内存泄漏,好的方法来检测呢?感谢

+0

感谢您的回答,但我不想增加我的堆大小,我想我可能需要找到一个好的算法。 – MemoryLeak 2009-08-12 13:16:02

+2

@Hooligan:告诉我们为什么要将数据加载到矢量中,也许我们可以为您提供一个好的算法。 – Brian 2009-08-12 13:31:19

+0

我们的旧程序遇到了这样一个超出内存的错误,所以我需要优化它,程序将所有数据加载到字段中,然后在此基础上进行处理。 – MemoryLeak 2009-08-12 13:47:29

回答

7

你的JVM提供更多的内存(通常使用-Xmx/-Xms)或不全部数据加载到记忆。

对于海量数据的许多操作,有一些算法不需要同时访问所有数据。一类这样的算法是divide and conquer algorithms

0

让你的程序中使用更多的内存或更好的重新思考战略。你真的需要这么多的数据在内存中吗?

+0

@JoshJordan tx编辑 – 2009-08-12 13:10:29

1

您可以尝试增加堆大小:

java -Xms<initial heap size> -Xmx<maximum heap size> 

默认为

java -Xms32m -Xmx128m 
+0

最大值将是1024米,这取决于您的平台(似乎最大可分配内存块)。 – 2009-08-12 13:07:52

+1

他说这个程序在38000行数据后抛出了OutOfMemoryError,我认为还有更多,他不能继续增加堆大小来跟上。 – 2009-08-12 13:10:53

+0

据我所知,没有最大值。我用4GB堆运行。 – Tommy 2009-08-12 13:13:21

1

你真的需要在内存中存储这样一个大对象吗?

根据您对该数据所做的操作,您可能需要将其拆分为较小的块。

1

按部分加载数据部分。这不会让您同时处理所有数据,但您不必更改提供给JVM的内存。

1

也许优化你的数据类?我已经看到有人使用Strings来代替本地数据类型,例如在存储内存中的相对少量的数据对象时给出OutOfMemoryError的每个类成员的int或double。看看你没有复制你的对象。而且,当然,增加堆大小:

的java -Xmx512M(或任何你认为必要的)

3

如果你必须在内存中的所有数据,尽量缓存共同出现的对象。例如,如果您正在查看员工记录并且他们都有工作职位,请在加载数据时使用HashMap并重新使用已找到的职位。这可以大大降低您使用的内存量。

另外,在你做任何事情之前,使用一个探查器来查看内存在哪里被浪费,并检查是否可以垃圾收集的东西没有引用浮动。同样,String是一个常见的例子,因为如果你使用的是2000 char字符串的前10个字符,并且你使用了substring而不是分配一个新的String,你实际上有一个对char [2000 ]数组,其中两个索引指向0和10.同样,一个巨大的内存浪费。

1

您可以使用探查器运行您的代码,以了解如何以及为何内存被吃掉。在循环中调试您的方式并观察正在实例化的内容。他们中有许多人; JProfiler,Java Memory Profiler,见list of profilers here等等。

0

我知道你正试图将数据读入矢量 - 否则,如果你试图显示它们,我会建议你使用NatTable。它专为将大量数据读入表格而设计。

我相信这可能会派上用场。

0

使用内存映射文件。内存映射文件基本上可以随意增大,而不会碰到堆。它确实要求您以解码友好的方式对数据进行编码。 (比如,为数据中的每一行保留一个固定大小,以便快速跳过多行)是有意义的。)

Preon允许您轻松处理。这是一个框架,旨在完成二进制编码数据,Hibernate为关系数据库完成的工作,以及JAXB/XStream/XmlBeans到XML。