2010-10-01 89 views
1

我有一个非常大的字符串,当我用Java读取它时,出现内存不足错误。实际上,我需要将所有这些字符串读入内存,然后分割成单独的字符串并根据值进行排序。这样做的最佳方式是什么?将长字符串读入内存

感谢

+4

你提供最大的内存限制为VM参数如:-Xmx500m.Which会允许你的内存为500 MB,为您的程序。 – Emil 2010-10-01 04:39:49

+0

我的意思是数据难以适应我的记忆。 – Boolean 2010-10-01 04:43:52

+0

尝试内存映射files.Though我不知道如何做你的情况,因为它不清楚你的实现是如何。 – Emil 2010-10-01 05:00:38

回答

4

哪里你的大字符串来自堆的大小?正如你所说的那样,我认为它来自一个文件。你是否需要知道整个字符串以知道在哪里分割它?如果没有,你可以直接读取char字符,直到你点击一个分割标记,把所有字符都读到字符串中,然后开始读取下一个字符串。你会粗略地知道在哪里对刚读过的单个字符串进行排序吗?如果是这样,您可以在第一次运行时编写部分字符串来分隔文件(例如,当您按字母顺序对字符串进行排序时,所有以字母A开头的字符串转到A.tmp)。之后,您可以对(创建文件的内容)(希望现在足够小以适应您的内存)进行排序,并最终将内容附加到新的输出文件。

2

如果你是受内存限制,那么你可以尝试申请其他归并排序增加使用虚拟机参数-Xmx和-Xms

1

如果您希望Hadoop能够“逐行”处理100 GiB apache日志文件,您的操作基本上与您想要的一样:将大量文本拆分为多个部分。

这样做,在Hadoop的(如您标记这个问题)的正常方式是使用它使用LineRecordReader它使用LineReader到文本文件分割的“结束行”分离的TextInputFormat。你想要的东西基本上与一个区别相同:拆分不同的东西。

对结果值(在Hadoop中)进行排序基本上是通过使用所谓的“Secondary Sort”(See the Hadoop examplethe explanation in Tom's book)来完成的。

所以,我建议做是

  1. TextInputFormat/LineRecordReader/LineReader读取并提取基于您的字符串的各个部分分离器自己的变化。
  2. 创建一个映射,重写信息以进行二级排序。
  3. 创建正确的分区,组和键比较器类/方法进行排序。
  4. 创建一个reduce,您可以在其中收到您可以进一步处理的排序信息。

HTH

0

你可以看一下 External sorting algoritmhs

+0

是的,但在这个细节层次上进入这种算法是我宁愿留给像Hadoop这样的框架的实现者。 – 2010-10-01 12:57:11