妈呀,内存又爆了

最近写了一个从postgresql到hbase导表job。pg中存的是text,有的条目还是很大的。 一开始没怎么注意,就用了200个线程导,发现很快内存就到上限了。回头看代码,也没啥问题,都是GC友好的。于是线程数降到100,内存还是慢慢的爆了。现象就是内存不断上涨,基本不下降,phoenix client在commit的时候会报奇怪的exception,这个时候job基本就不能工作了。挂上GC log继续跑了一次,发现GC基本无效,但还是有效的,只不过回收的很少。 回头再看业务,我是根据customer id出发导表的,每个id会有n条记录,每条记录是一个长度为m的数组,需要序列化整个数组,然后打平。我猜问题就出现在这里了,很多customer的记录会有上万条,每条记录的数组长度如果太长的话,这个序列化之后的list会很大。但是这些对象只是大而已,导的速度还是很快的,导完就可以扔掉了。 于是尝试使用G1GC,虽然没有都没有调大heap空间,但是效果明显改善,GC十分有效。 默认Parallel collector的log,连续几次的full gc: 6.783: [Full GC (Metadata GC Threshold) [PSYoungGen: 2880K->0K(424960K)] [ParOldGen: 8036K->8024K(52736K)] 10916K->8024K(477696K), [Metaspace: 20761K->20761K(1069056K)], 0.1111975 secs] [Times: user=0.11 sys=0.00, real=0.11 secs] 11.710: [GC (Metadata GC Threshold) Desired survivor size 11010048 bytes, new threshold 1 (max 15) [PSYoungGen: 413842K->7153K(424960K)] 421867K->22659K(477696K), 0.0436894 secs] [Times: user=0.04 sys=0.01, real=0.04 secs] 11.754: [Full GC (Metadata GC Threshold) [PSYoungGen: 7153K->0K(424960K)] [ParOldGen: 15506K->19928K(86016K)] 22659K->19928K(510976K), [Metaspace: 34780K->34780K(1081344K)], 0.2035734 secs] [Times: user=0....

November 17, 2017 · 2 min · magicalne

Memory model

内存模型是一个相对底层的概念,对于很多编程语言来说,内存模型是对程序员屏蔽的概念。但是如果是涉及并发编程的话,内存模型是一个逃不开的知识点。本文是对自己理解的Java Memory Model的知识梳理。 What is reordering? 你所写的java代码会被compiler、JIT、cache、instructions、CPU执行时重排序。 Source order – how you write the code – Naïve expectation that everything happens exactly as written • Program order – generated machine code presented to the CPU – “Any resemblance to source order is purely coincidental” – It’s all about performance! As long as you can’t tell the difference • Execution order – how the hardware actually executes the code – Speculative execution, instruction reordering, caching, pipeline stalls – It’s all about performance!...

November 17, 2016 · 3 min · magicalne