做一个计算,需要读入两个文本文件,一个210M,一个19.2G,因为在处理过程中要频繁访问(一次运行要访问几千次),所以选择直接读入内存,用的是map。
现在借用了一台工作站,内存64G,-XMX60000,读第二个文件的时候走不下去了,没有报错,但昨天读到今天还没读完。没辙了,请大家指点!

解决方案 »

  1.   

    用Map处理这么大的文本文件,简直是难为jvm啊
    首先,针对于19.2G的文本文件,估算一下,大概为20615843021B,好,假设你拆分成1kw个条目,那么每个条目的大小为20615B,对于20615B的字符串,共有255^20615种组合。Hash散列函数映射后的元素为Int型,共有255^4个值,那么,hash的碰撞率为255^20615/255^4=255^20611,好吧,hashMap的“Hash”已经差不多报废了。那么假设,hash冲突率为0,那么拆分成1kw个条目,每次执行hash计算操作时,需要进行20615次Hash迭代,jvm表示压力很大另外,你设置的-XMX是60000,但是,对于大小为20615的字符串,差不多是直接进老年代了,如果你处理一次后就丢了,那么在进行垃圾收集时,就会对GC产生难以描述的压力。细思恐极对于这么大的文本操作,还是别想着用HashMap了,用一个String包下来,然后通过用HashMap来记录起始与终止位置,然后用SubString来处理吧。别难为可怜的HashMap了
      

  2.   

    谢谢解答!我的数据集里面都是一行一行小数据,item-item-number,最大的item的长度也只有260。关键是数量太大了,又要频繁使用。如果用String读入,再做定位标注的话,这个标注的大小也很恐怖。也考虑过直接放数据库里面,但估计效率影响比较大,用整个数据集的十分之一跑过,用map全读入内存的方式,也要好几天才会出结果,如果放数据库,真不知道效率会成啥样了。再请大家帮指点,谢谢!
      

  3.   

    这种大文件想要一次性的读入内存是不太现实的,除非你的机器超级棒。的19G文件既然是按行算的,那么是否可以将19G的文本进行分片,每个文本划分为512M或者是256M,并为每个文本编号。这样每次都按照编号进行查找读取,虽然速度不是很快,但相对来说还行。
    并且是否楼主的这19G文件中的所有条目的匹配频率都是一样的么?如果不一样可以选择把高匹配的先录入内存,低匹配的放在文件里。当内存中找不到的时候再去找文件。
    还有楼主的数据是否有规律,如果有规律是否可以按照规律进行划分查找。
    只是思路,具体还要楼主实际情况进行考虑。