返回信息流@nuanyangyang
程序的开始是读入一个文件里的数据,数据的格式是:
每一行为三个字段,例如:
2,3,0
一共是1.2亿行。我把它读到一个字典里面。我用的数据结构是:HashMap<Integer,LinkedList<Node>>
键是每一行的第一个数字,值是一个LinkedList,Node有两个字段:
Node{
int ID;
int distance;
}
分别是每一行的第二个数字和第三个数字。也就是说每一行会产生一个node。
然后每50行放入一个LinkedList,也就是说每个LinkedList有50个node。我估算了一下,需要的内存是:
0.12G*(4+4+4)=1.44G
4是int类型占的字节数。加上node封装,linkedlist的使用可能会需要一些额外的内存,我给java虚拟机分配了6G的内存上线。
程序运行的时候,发现开始读入的速度还是很快的,内存涨的很快,但cpu一直维持在较低水平,大概40-50%,但是当读入到2300万行的时候就卡主了,多次运行到这时都停住了,任务管理器显示java程序只占用了2.3G的内存,但很快cpu使用率达到了100%。
我想问下大家,这是什么原因呢,是因为我使用了Node封装和LinkedList导致需要更多的内存吗。需要多多少呢。而且为什么我为这个java程序分配了6g的内存,就算是内存不足,也不应该卡在2.3G这个地方啊。难道是我分配内存的方法不对?大家都是怎么给单独的java程序分配内存的?
拜谢啊。[ema1][ema7][ema7][ema7]
这是一条镜像帖。来源:北邮人论坛 / java / #34277同步于 2014/8/31
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
大神们,来帮我看看这个java 内存问题
binxin
2014/8/31镜像同步6 回复
订阅后,新回复会通过你的通知中心匿名送达。
6 条回复
HashMap是按键存的吧,键不一样,hash值就不一样,bucket位置也不一样,即便发生hash相同碰撞,HashMap是按LinkedList来解决碰撞,你这个的情况感觉好像HashMap里的每个bucket里头存个LinkedList,LinkedList里头又存着只会存一个Node的LinkedList。
不知道你是咋做到你的LinkedList里头存50的Node呢?内存就不懂了,还是等大神吧。
【 在 binxin 的大作中提到: 】
: @nuanyangyang
: 程序的开始是读入一个文件里的数据,数据的格式是:
: 每一行为三个字段,例如:
: ...................
内存占用率远远比你想象的大。
Java虚拟机里,每个对象至少有两个word的头,一个指向TIB(存着内存信息),另一个放一些垃圾回收用的头、锁等。所以你的一个node估计一下至少占用16字节,有可能更多。根据linkedlist的实现,每个linkedlist的节点估计也有24-32字节的空间,linkedlist本身也有一定的空间占用。hashmap的key是Integer,也就是一个装箱类型,不只会占用4字节,起码还有8字节左右的头。如果你用64字节,所有的对象应该是8字节对齐的,所以单一个Integer就可能会占用16字节。HashMap本身也占用一些空间,起码和key的数量是线性的。所以每个key又起码多4-8个字节。
所以,实际占用的空间可能是你估计的2-3倍。
记得调整一下你的jvm的堆大小(-Xmx选项)。
试试用两个int[]数组,仅仅把所有数据都存起来,看看程序死不死。如果这样都不行,那就是内存太小了。
如果物理内存不够了,机器会把数据放到硬盘上的交换空间上去,看上去就是硬盘一直转,程序特别慢。
你的机器的物理内存多大?操作系统是32位的还是64位的?Java虚拟机呢?别不小心在64位机上运行了32位程序。
【 在 nuanyangyang 的大作中提到: 】
:
: 内存占用率远远比你想象的大。
: Java虚拟机里,每个对象至少有两个word的头,一个指向TIB(存着内存信息),另一个放一些垃圾回收用的头、锁等。所以你的一个node估计一下至少占用16字节,有可能更多。根据linkedlist的实现,每个linkedlist的节点估计也有24-32字节的空间,linkedlist本身也有一定的空间占用。hashmap的key是Integer,也就是一个装箱类型,不只会占用4字节,起码还有8字节左右的头。如果你用64字节,所有的对象应该是8字节对齐的,所以单一个Integer就可能会占用16字节。HashMap本身也占用一些空间,起码和key的数量是线性的。所以每个key又起码多4-8个字节。
: ...................
我的机器是64bit,内存8G,怎么看程序是32位还是64位啊,暖神,是跟我的eclipse位数有关吗?我再v2ex上问了问,有说声明hashmap的时候初始化大小,这样就不会频繁的rehash,先前卡在2.3g处,并且cup100%,原因是此处进行了rehash。可是,我明明给它分配了参数:
-Xms1024m
-Xmx6144m
要卡也应该是卡在6G处,怎么会在2.3G呢。暖神,帮我看看。
【 在 nuanyangyang 的大作中提到: 】
:
: 内存占用率远远比你想象的大。
: Java虚拟机里,每个对象至少有两个word的头,一个指向TIB(存着内存信息),另一个放一些垃圾回收用的头、锁等。所以你的一个node估计一下至少占用16字节,有可能更多。根据linkedlist的实现,每个linkedlist的节点估计也有24-32字节的空间,linkedlist本身也有一定的空间占用。hashmap的key是Integer,也就是一个装箱类型,不只会占用4字节,起码还有8字节左右的头。如果你用64字节,所有的对象应该是8字节对齐的,所以单一个Integer就可能会占用16字节。HashMap本身也占用一些空间,起码和key的数量是线性的。所以每个key又起码多4-8个字节。
: ...................
还有人说,可以用Gnu Trove 里的TIntObjectHashMap, TIntArrayList,暖神用过这东东吗?[ema41]
【 在 binxin 的大作中提到: 】
: 我的机器是64bit,内存8G,怎么看程序是32位还是64位啊,暖神,是跟我的eclipse位数有关吗?我再v2ex上问了问,有说声明hashmap的时候初始化大小,这样就不会频繁的rehash,先前卡在2.3g处,并且cup100%,原因是此处进行了rehash。可是,我明明给它分配了参数:
: -Xms1024m
: -Xmx6144m
: ...................
你的操作系统呢?如果是linux,用uname -a看,如果是windows,按win+pause键看。
你的jvm的话,你当初安装的时候应该留意过安装包文件名。
【 在 nuanyangyang 的大作中提到: 】
:
: 你的操作系统呢?如果是linux,用uname -a看,如果是windows,按win+pause键看。
: 你的jvm的话,你当初安装的时候应该留意过安装包文件名。
: ...................
操作系统是windows7,jdk是64位没问题。