我有一个文件大概是250M,每一行存的是ID以及用户介绍等基本信息。我把文件的内容读到HashMap里,key是用户的ID,value是用户的基本信息。为什么一个250M的文件读到内存后整个java程序占用了800M。有没有什么办法把内存限在一个低的范围呢?现在可是3倍于原始大小呀。这是什么原因引起的呢?望高手帮忙解答一下

解决方案 »

  1.   

    用内存映射吧,一次性读进来挺大的
    http://zhanglihai.javaeye.com/blog/88067
      

  2.   

    java对象占用内存要远大于文件中的数据。好像{class java.lang.Object} size = 8 bytes{class java.lang.Integer} size = 16 bytes{class java.lang.Long} size = 16 bytes{class java.lang.Byte} size = 16 bytes{class [Ljava.lang.Object;} size = 16 bytes //长度为0的Object类型数组{class [Ljava.lang.Object;} size = 16 bytes //长度为1的Object类型数组{class [Ljava.lang.Object;} size = 24 bytes //长度为2的Object类型数组 http://mercyblitz.javaeye.com/blog/710998针对你的需求,我觉得用memcache似乎比较对头。
      

  3.   

    不能用内存映射文件呀,因为我要把数据缓存到Hashmap里,这样可以根据用户的的ID直接取到内容
      

  4.   

    NIO的内存映射机制确实可以解决OutOfMemory,但问题是Java的这种技术太鸡肋了,你从MappedByteBuffer里面读取字节,和直接从磁盘文件中读取的效率差不多的。主要NIO的效率体现在非阻塞时的效率。
      

  5.   

    像这样的问题建议不要把所有的都取到内存存到hashmap里,这样很容易导致内存溢出。建议把所有的都读取出来之后存入一个数据库表中,把key设置成主键,获取数据的效率应该还是比较快的。
      

  6.   

    楼主问的是原因,有人解释下么?
    我觉得因为内存里的存放方式和磁盘不一样。所以,相同的信息量,不同的空间使用量。
    比方说:long,在磁盘上可能用字符串的方式存储,“1”也可以是long,但是在内存里呢,就是1也是Long,8个字节的基本开销是少不了的
    还有:hashmap和文件存储方式不一样。 文件是流式的,下个字节就是下个数据,具体数据的分隔和解析,是使用者的事,但是hashMap就不一样,它需要把数据分隔成基本类型的数据,还要把若干个基本数据组合成一个类实例,你想,如果是你,你怎么做?一定需要一些辅助字节来表示这个类的边界,成员的边界等等;
    还有,Hashmap不是数组,它很有可能是稀疏的,又要一些空间
    总之,不同的存储结构,存储相同的信息量,大小可以差很多。
    有个故事听过吧?外星人用一个棒子上的一点,带走了所有地球的数据,问咋整的?它说:这个点把棒子分成了两个部分,这两个部分的比值就是一个有限小数,不过有限是有限,长度比较长,有10^12345678次方那么长,回去我们用我们星球的超级尺子一量,两边一除,就得到这个数字序列了。(这个序列就是信息内容,算我废话多,还补充这么一句)
      

  7.   

    对于存取速度,内存>数据库>内存映射
    既然内存需要占的空间无法减少,建议还是使用数据库吧
      

  8.   

             在读入文件的时候,java需要交互的内存空间,通常这个空间都比实际文件的size要大。 所以,你要减少读文件时,产生的交互内存消耗。  
      

  9.   

    用空间换时间,hashmap这件事目前来说还是memcache来的专业
      

  10.   


    贴下代码吧 会不会是缓冲的问题呢?
    不用HashMap 换链表看看
      

  11.   


    不太了解HashMap是怎么实现的 也没有遇到过类似的问题 这位大哥的意思是不是说HashMap在长度不够的时候拓展容器长度那一步骤有问题哦?
      

  12.   


    应该是楼主用java做的数据封装太低效了,浪费很多空间。
    我的意思是,与其自己费力写封装,不如直接用memcache,将来扩展起来更容易。