夜深了,问题还没解决,JAVA占用大内存的问题

giantman 2010-09-13 11:41:50
我有一个文件大概是250M,每一行存的是ID以及用户介绍等基本信息。我把文件的内容读到HashMap里,key是用户的ID,value是用户的基本信息。为什么一个250M的文件读到内存后整个java程序占用了800M。有没有什么办法把内存限在一个低的范围呢?现在可是3倍于原始大小呀。这是什么原因引起的呢?望高手帮忙解答一下
...全文
210 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
歪嘴鱼 2010-09-14
  • 打赏
  • 举报
回复
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似乎比较对头。
shenzhaozhi 2010-09-14
  • 打赏
  • 举报
回复
围观,拿分
BearKin 2010-09-14
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 zhblue 的回复:]

引用 17 楼 bearkin 的回复:

引用 15 楼 zhblue 的回复:

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


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


应该是楼主用java做的数据封装太低效了,浪费很多空间。
我的意思……
[/Quote]

学习咯
歪嘴鱼 2010-09-14
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 bearkin 的回复:]

引用 15 楼 zhblue 的回复:

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


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

应该是楼主用java做的数据封装太低效了,浪费很多空间。
我的意思是,与其自己费力写封装,不如直接用memcache,将来扩展起来更容易。
BearKin 2010-09-14
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 zhblue 的回复:]

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

不太了解HashMap是怎么实现的 也没有遇到过类似的问题 这位大哥的意思是不是说HashMap在长度不够的时候拓展容器长度那一步骤有问题哦?
BearKin 2010-09-14
  • 打赏
  • 举报
回复
[Quote=引用楼主 giantman 的回复:]
我有一个文件大概是250M,每一行存的是ID以及用户介绍等基本信息。我把文件的内容读到HashMap里,key是用户的ID,value是用户的基本信息。为什么一个250M的文件读到内存后整个java程序占用了800M。有没有什么办法把内存限在一个低的范围呢?现在可是3倍于原始大小呀。这是什么原因引起的呢?望高手帮忙解答一下
[/Quote]

贴下代码吧 会不会是缓冲的问题呢?
不用HashMap 换链表看看
歪嘴鱼 2010-09-14
  • 打赏
  • 举报
回复
用空间换时间,hashmap这件事目前来说还是memcache来的专业
j43350860 2010-09-14
  • 打赏
  • 举报
回复
在读入文件的时候,java需要交互的内存空间,通常这个空间都比实际文件的size要大。 所以,你要减少读文件时,产生的交互内存消耗。
liufeng0209 2010-09-14
  • 打赏
  • 举报
回复
对于存取速度,内存>数据库>内存映射
既然内存需要占的空间无法减少,建议还是使用数据库吧
clariones 2010-09-14
  • 打赏
  • 举报
回复
楼主问的是原因,有人解释下么?
我觉得因为内存里的存放方式和磁盘不一样。所以,相同的信息量,不同的空间使用量。
比方说:long,在磁盘上可能用字符串的方式存储,“1”也可以是long,但是在内存里呢,就是1也是Long,8个字节的基本开销是少不了的
还有:hashmap和文件存储方式不一样。 文件是流式的,下个字节就是下个数据,具体数据的分隔和解析,是使用者的事,但是hashMap就不一样,它需要把数据分隔成基本类型的数据,还要把若干个基本数据组合成一个类实例,你想,如果是你,你怎么做?一定需要一些辅助字节来表示这个类的边界,成员的边界等等;
还有,Hashmap不是数组,它很有可能是稀疏的,又要一些空间
总之,不同的存储结构,存储相同的信息量,大小可以差很多。
有个故事听过吧?外星人用一个棒子上的一点,带走了所有地球的数据,问咋整的?它说:这个点把棒子分成了两个部分,这两个部分的比值就是一个有限小数,不过有限是有限,长度比较长,有10^12345678次方那么长,回去我们用我们星球的超级尺子一量,两边一除,就得到这个数字序列了。(这个序列就是信息内容,算我废话多,还补充这么一句)
rumlee 2010-09-14
  • 打赏
  • 举报
回复
像这样的问题建议不要把所有的都取到内存存到hashmap里,这样很容易导致内存溢出。建议把所有的都读取出来之后存入一个数据库表中,把key设置成主键,获取数据的效率应该还是比较快的。
heartraid86 2010-09-14
  • 打赏
  • 举报
回复
一定要把所有数据全部读入内存才可以处理吗,能不能读取一部分,处理一部分
WANGYQ_412 2010-09-14
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 thefirstz 的回复:]
用内存映射吧,一次性读进来挺大的
http://zhanglihai.javaeye.com/blog/88067
[/Quote]

顶!
heartraid86 2010-09-14
  • 打赏
  • 举报
回复
NIO的内存映射机制确实可以解决OutOfMemory,但问题是Java的这种技术太鸡肋了,你从MappedByteBuffer里面读取字节,和直接从磁盘文件中读取的效率差不多的。主要NIO的效率体现在非阻塞时的效率。
giantman 2010-09-14
  • 打赏
  • 举报
回复
不能用内存映射文件呀,因为我要把数据缓存到Hashmap里,这样可以根据用户的的ID直接取到内容
shehun 2010-09-14
  • 打赏
  • 举报
回复
这个也需要学习一下,
qingtianliuyun 2010-09-14
  • 打赏
  • 举报
回复
对我来说,又一个新知识点啊,受教了
24K純帥 2010-09-14
  • 打赏
  • 举报
回复
内存映射文件,学习了。。
昵称很不好取 2010-09-13
  • 打赏
  • 举报
回复
用内存映射吧,一次性读进来挺大的
http://zhanglihai.javaeye.com/blog/88067

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧