1
plucury 2014-08-31 22:22:32 +08:00 1
怀疑是内存问题可以用jmap打印内存占用情况。但是既然cpu占用100%的话,可以考虑用jstack打印线程运行命令来看看,如果看起来没问题考虑启动时打印GC日志,看看是否有频繁的full gc
|
2
cloud107202 2014-08-31 22:39:56 +08:00 1
内存问题不是很了解,说点我想到的
1. 插入过程有没有并发调用HashMap.get(),这个可能会发生死锁http://coolshell.cn/articles/9606.html 2. 如果可能的话,考虑下redis这类内存数据库 |
3
undeflife 2014-08-31 23:15:17 +08:00 1
如果是内存问题的话 应该会报OOM 或OOM:PermGen space的
查查文件在2300万行左右是否有什么问题导致你在读取文件的时候卡住 读取文件的代码会不会有什么bug引起问题 怀疑LinkedList 的话完全可以把LinkedList换成Node[50] |
4
ahcat 2014-08-31 23:25:15 +08:00 via iPhone 1
换一个64位的jvm?
|
6
lehui99 2014-09-01 00:10:58 +08:00 via Android 1
HashMap的内部实现是数组+链表,在key的数量扩大时有可能导致数组和所有链表的内存重新分配,并将其中所有的引用重新赋值到新的数组中并重新生成所有的链表,十分耗时。可以看一下HashMap的具体实现的详细分析: http://blog.csdn.net/blog/vking_wang/14166593 ,中的最后一段:rehash过程。
解决方法是在HashMap初始化时指定initCap,如: new HashMap(130000000/50) 。 |
7
akfish 2014-09-01 06:09:39 +08:00 via iPad 1
数据固定么?需要改动么?改了需要写回文件么?
既然数据格式已知,完全没必要用HashMap和LinkedList,直接分配一个巨大的Array,减少overhead。对应key的index很容易计算,或者用一个HashMap<Integer, Integer>来记录每个key的第一个index。 另外就是一次完成分配可以提高分配到连续内存的概率,减少碎片的产生。 |
8
nybux 2014-09-01 08:43:50 +08:00 1
HashMap在构造的时候加个参数
new HashMap<>(2400001); |
10
stevenyou 2014-09-01 09:27:39 +08:00 2
楼主对内存的估算不太正确, 没有算进去java object , 和HashMap 的overhead.
一个空object 会用16 bytes, Node 里有两个int, 也就是一个Node 会在Heap里用掉32 bytes 一个空LinkedList里应该有4个private fields 会占用 (4+2) * 8 = 48 bytes 一个LinkedList用的memroy 是 48 + 24* size_of_list , 你的size 是50 , 也就是 1248 bytes HashMap 的内存占用是 32 * SIZE + 4 * CAPACITY bytes , 你的size 是 120,000,000 / 50 . default load factor 是0.75, capacity 就是 (120,000,000 / 50) / 0.75. 估算一下, 一共会用7个多G 的内存。 另外hashmap rehash 是很快的,这个数据量不是很大, cpu没有吃满应该是别的原因,比如disk io, 看一下你top 里的 wa 是多少。 楼主也可以把代码贴出来给大家看看,分析一下。 |
11
buptlee OP @cloud107202 没有并发问题,有没有redis的入门资料呢,贴个链接啥的,不太懂这个,嘿嘿。
|
12
stevenyou 2014-09-01 09:32:21 +08:00 1
cpu使用率后来达到了100% 应该是在rehash
|
14
stevenyou 2014-09-01 09:52:25 +08:00 2
|
15
stevenyou 2014-09-01 09:53:13 +08:00 1
|
16
buptlee OP @stevenyou 我试了在声明hashmap时初始化个数的方法:
HashMap<Integer,LinkedList<Node> > dist_matrix= new HashMap<Integer ,LinkedList<Node>>(2173370); 结果还是停在了2300万行的位置然后cpu到100%了,查看进程管理器,发现内存只占用了2.2G左右,但我给这个程序分配了最大6G的内存,分配的方法是: 在Debug Configuration里的(x)=Aguments的Program arguments下添加如下参数: -Xms1024m -Xmx6144m -XX:PermSize=1024m -XX:MaxPermSize=6144m 您看看是不是我分配方法有问题,我的疑问是,就算是内存不足,也不应该卡在2.2G这个地方,而是应该在6G,或者至少应该4,5G啊。thanks. |
17
stevenyou 2014-09-01 10:10:34 +08:00 2
跑的时候在java opts里加个 -Xrunhprof:cpu=samples,interval=10,depth=8
程序停掉的时候目录下会多一个"java.hprof.txt", 看那里面profiler 显示哪个function 用的时间多。 这个是发现问题最容易和方法。 hprof是java 自带的profiler |
18
stevenyou 2014-09-01 10:20:21 +08:00 1
还有,你用的内存都是在heap里,所以不需要设 PermSize , default size 32M or 96M based on 32bit or 64 bit is big enough
|
19
buptlee OP 是应该在program arguments下设置还是VM arguments下设置呢?
下面的参数可以吗? -Xms1024m -Xmx6144m |
20
stevenyou 2014-09-01 10:33:20 +08:00 1
VM, 传给java的
如果你放在program arguments里, 就可以解释为什么会卡在2.3G了, jvm deault heap size 是2048m, jvm在 GC , 在3 次full GC,释放不了2%内存的话就会throw out of memory exception: excessive GC time |