GreenTeaJUG活动 第20期 杭州

时间:2015-10-18
地点:杭州文一西路969号阿里巴巴西溪园区1-2-7曼陀山庄
组织:@JianhaoMo

主题:Understanding Java Garbage Collection
讲师:Gil Tene,Azul 联合创始人,副总裁,CTO,从95年开始基于Java技术做产品,浸淫虚拟机技术20年。其载有C4 GC算法的Zing JVM能处理TB级别的Java堆而不用担心停顿。Gil 也是Azul的JCP执行委员会的代表。

主题:Java调试那点事
介绍Java调试体系JPDA、 JVMTI、JDWP、JDI等技术,并附有实例源码。
讲师:邱小侠(@肥侠xx),阿里集团客户体验事业群 高级技术专家

报名

活动报名请按照如下格式发邮件到event@greenteajug.cn
主题:GreenTeaJUG活动 第20期 杭州
姓名:XXX
手机号码:xxxxxxxxxxx (需接收入园短信,请确保正确)
邮箱:xxxx@xxx.xxx
公司:xxxx有限公司
职位:xx工程师
Java使用年限:x年

GreenTeaJUG活动 第19期 安利一下近三年的JVM Language Summit

时间:2015-08-13
地点:网络
组织:@JianhaoMo

JVM Language Summit 2015刚开完。

搞这个活动就是觉得关注JVM Language Summit的人太少,主动安利一下。

近三年的链接如下:

JVM Language Summit 2015

JVM Language Summit 2014

JVM Language Summit 2013

GreenTeaJUG活动 第18期 Adopt OpenJDK 翻译计划

时间:2015-08-02
地点:网络
组织:@JianhaoMo

转载自并发编程网 – ifeve.com

并发编程网同GreenTeaJUG和Adopt openjdk官方达成合作,组织翻译Adopt OpenJDK的中文版,翻译完成后会从官网链接到中文版,有兴趣的同学可以在翻译计划评论领取任务进行翻译,请尽量在领取后2天内完成翻译。目前已经翻译了第三、四、八章。

GreenTeaJUG活动 第17期 GreenTeaJUG特别奖(一万元现金)

时间:2015-07-19
地点:网络
组织:@JianhaoMo

GreenTeaJUG特别奖

获奖人:孙宇 (阿里花名:洪熙,@洪熙

获奖理由:从零开始,默默坚持五年,专注Hotspot JVM GC代码。

奖金:人民币一万元现金

奖金赞助来源:莫简豪个人

性能调优利器——PerfJ

PerfJ是我业余时间开发的一个小工具,现在来说不建议用在生产环境,因为还没有得到更多案例的证明。

平时我们在做Java程序Profiling时,基本上使用YJP, hprof, jvisualvm这样的工具,还有for i in {1..100}; do jstack $pid > $i; done;这些工具基本上两个原理,一个是sampling(采样),一个是instrument(注入一些信息到方法里面,然后统计)。

这些工具有些问题不能解决:

如果是网络io,磁盘io等问题,基本只能看到epollWait, socket/file的read这一层,看不到更深层次的原因;
如果看到Java程序占用CPU很高,用上面工具只能估计。先用top看到线程级别,看哪个线程CPU搞,然后再jstack。

即系统工具都无法上达Java这一层。

讲师:周敏(@MinZhou

整理:以亭

1. Principle behind PerfJ

PerfJ是我业余时间开发的一个小工具,现在来说不建议用在生产环境,因为还没有得到更多案例的证明。

平时我们在做Java程序Profiling时,基本上使用YJP, hprof, jvisualvm这样的工具,还有for i in {1..100}; do jstack $pid > $i; done;这些工具基本上两个原理,一个是sampling(采样),一个是instrument(注入一些信息到方法里面,然后统计)。

这些工具有些问题不能解决:

  • 如果是网络io,磁盘io等问题,基本只能看到epollWait, socket/file的read这一层,看不到更深层次的原因;
  • 如果看到Java程序占用CPU很高,用上面工具只能估计。先用top看到线程级别,看哪个线程CPU搞,然后再jstack。

即系统工具都无法上达Java这一层。

PerfJ的原理

linux perf 是一个强大的profiling, tracing的工具集, 包含在kernel代码树里,但perf对于java的程序没有办法。

首先, java很多程序被Just in time compiling了, perf不知道java函数的原始名字。

其次,JVM由于历史原因把frame pointer的register给去了,所以无法爬栈。

PerfJ其实只是linux perf的一个包装。解决了第一个问题,JIT,原理是通过JVMTI把perfj attach到目标JVM,将它JIT后各函数的原始函数名和地址的对照拿出来,写到/tmp/perf-$pid.map文件中,之后perf会加载这个文件,从而统计出java程序的一些信息。第二个问题可以通过升级JDK到8u60 b19以上解决(见后面)。

2. Install perf, PerfJ, java 8u60 b19

安装前准备:

Linux 64bit 物理机;

 

(1)安装perf工具

centos系:yum install perf.x86_64;

ubuntu:apt-get install linux-tools-common linux-tools-generic linux-tools-`uname -r`

(2)安装PerfJ

checkout the source from github

git clone https://github.com/coderplay/PerfJ.git

and run below in the future buildingcd PerfJ

./gradlew releaseTarGz

如果没有装gcc,可以到http://blog.minzhou.info/PerfJ/PerfJ-1.0.tgz这里下载,但不保证都能用 🙂

(3)下载火焰图生成工具FlameGraph

git clone https://github.com/brendangregg/FlameGraph.git

  • 安装最新JDK

https://jdk8.java.net/download.html

务必是jdk 8u60 b19以上!

如果打不开,可以到这里下载:http://share.weiyun.com/cd36ccd7f6e837bd4699f3a1448f31e8

下载后解压,修改PATH和JAVA_HOME环境变量。

export JAVA_HOME=新jdk路径

export PATH=$JAVA_HOME/bin:$PATH

3. Show some flame graph

http://blog.minzhou.info/perfj/perfj.svg

1

图中,绿色是Java代码,黄色是JVM代码,红色是Kernel代码,宽度表示占用CPU时间。

4. Building PerfJ and untar the ball

解压perfj-1.0.tgz

cd perfj-1.0/

运行:bin/perfj list, 查看所支持的事件。运行截图:

2

5. Context Switch

下载模拟context switch的java代码:http://blog/minzhou.info/perfj/ContextSwitchTest.java

编译:javac –cp . ContextSwitchTest.java

运行:java –cp . ContextSwitchTest

开启另一窗口,运行vmstat 1,发现cs很高。

使用java –cp . –XX:+PreserveFramePointer ContextSwitchTest,开启frame pointer

同时另一窗口运行:bin/perfj record -e cs  -g -p `pgrep -f ContextSwitchTest`

跑一段时间后,ctrl + C,然后bin/perfj report –stdio

得到结果如下:

3

如果出现这种无法打开map文件错误:

4

可能是perfj版本问题。下载这个:http://blog.minzhou.info/perfj/perfj-1.0.tgz(打不开?用http://share.weiyun.com/ae0cb80416b3ca3d97fc1877aa1bde4a)就好了。

从这个程序的stack可以看出Unsafe.park会导致当前线程让出cpu, 引发context switch。

刚才那段代码是用来看context switch在哪里发生,以前的工具是没有办法的。

6. CPU cache miss example

下载代码:blog.minzhou.info/PerfJ/L1CacheMiss.java

编译:javac -cp . L1CacheMiss.java

运行:java -cp . -Xmx2g -XX:+PreserveFramePointer L1CacheMiss

捕获:bin/PerfJ record -e  L1-dcache-load-misses  -g -p `pgrep -f CacheMiss`

报告:bin/perfj report –stdio

cache hit比cache miss快几十倍。

5

通过上面看到,94%的cache miss是cachemiss这个函数造成的。

7. Homework , Threadpool comparison

时间关系,未做介绍

8. More complex examples, io request profiling

下载可执行程序:http://blog.minzhou.info/PerfJ/leveldb-benchmark.jar

直接运行: java -cp leveldb-benchmark.jar  -XX:+PreserveFramePointer org.iq80.leveldb.benchmark.DbBenchmark  –benchmarks=fillrandom  –num=100000000

捕获:bin/perfj record -F 99 -g -p `pgrep -f DbBenchmark`

-F是指sampling的频率为99Hz。

报告:bin/perfj report –stdio

9. Off cpu analysis

在cpu上运行的有时候不占程序最主要时间,有时候往往是网络在等,有时候是写了一个sleep代码,这个往往很难找。我们继续用刚才的leveldb 例子:

运行: java -cp leveldb-benchmark.jar -XX:+PreserveFramePointer org.iq80.leveldb.benchmark.DbBenchmark –benchmarks=fillrandom –num=100000000

捕获:bin/PerfJ record -e sched:sched_stat_sleep -e sched:sched_switch  -e sched:sched_process_exit -g -o ~/perf.data.raw -p `pgrep -f Benchmark`

因为我们可以知道系统scheduler的trace point,所以我们record三个事件,然后通过这三件事件的时间差,知道哪个是off CPU之后不干活。

注入:bin/PerfJ inject -v -s -i ~/perf.data.raw -o ~/perf.data

报告: bin/PerfJ report –stdio –show-total-period -i ~/perf.data

6

可以看到截屏的这些stack虽然不占CPU,但在off cpu的时候一直歇着,很有可能拖慢程序的执行。

我们可以看到LockSupport.park的jni实现里有JVM sleep,所以在抢java concurrent锁的时候,如果冲突很大,还可能被锁sleep一下了。大家可以线下在网络代码里试试off cpu。

这里有很多示例:

http://www.brendangregg.com/FlameGraphs/cpuflamegraphs.html

http://www.brendangregg.com/perf.html

大部分是perf的用法,大家也可以用perfj试试,大部分都可以用。

例如上面leveldb的例子我们可以分析IO:

bin/perfj record -e block:block_rq_issue -F 99 -g -p `pgrep -f DbBenchmark`

用这个看物理设备的块请求是谁操作的,是哪些java代码调用的,然后我可以看到这个stack:

7

知道了java代码位置,可以用ftrace看这个io request的io size,用了多少时间,是random io还是seq io。

https://github.com/brendangregg/perf-tools/blob/master/examples/iosnoop_example.txt

# ./iosnoop Tracing block I/O… Ctrl-C to end.

COMM             PID    TYPE DEV      BLOCK        BYTES     LATmssupervise        1809   W    202,1    17039968     4096       1.32supervise        1809   W    202,1    17039976     4096       1.30tar              14794  RM   202,1    8457608      4096       7.53tar              14794  RM   202,1    8470336      4096      14.90tar              14794  RM   202,1    8470368      4096       0.27tar              14794  RM   202,1    8470784      4096       7.74tar              14794  RM   202,1    8470360      4096       0.25tar              14794  RM   202,1    8469968      4096       0.24tar              14794  RM   202,1    8470240      4096       0.24tar              14794  RM   202,1    8470392      4096       0.23tar              14794  RM   202,1    8470544      4096       5.96tar              14794  RM   202,1    8470552      4096       0.27tar              14794  RM   202,1    8470384      4096       0.24[…]

 

像这样,perfj找到系统的事件之后,然后用ftrace跟踪详细的信息。

10. CPU flame graph

捕获成功后,会在当前目录下生成perf.data。利用这个文件可以绘制火焰图。

sudo mv perf.data ../FlameGraph

cd ../FlameGraph/

sudo perf script | ./stackcollapse-perf.pl > out.perf-folded

./flamegraph.pl out.perf-folded –colors java > PerfJ.svg

GreenTeaJUG活动 第16期 性能调优利器——PerfJ by 周敏

时间:2015-06-28
地点:网络
组织:以亭

主题:Perfj
讲师:周敏(@MinZhou

周敏

周敏, 暨南大学计算机硕士毕业学位. 主研方向: 大数据、分布式系统. 先后在阿里巴巴担任技术专家, 美国LinkedIn公司Staff Engineer , 现任美国Tango公司Senior Staff Engineer, 带领大数据基础研发团队. 多个Apache开源项目贡献者及提交者. 曾帮助Apache Spark团队获100TB数据排序世界记录. 现定居美国旧金山湾区.

Java作为服务端程序近年来大规模网站服务、大数据、机器学习等方面应用越来越广, 服务端程序的性能越来越关键。当前Java的性能剖析器,例如jvisualvm, jprofiler, YJP都只能从Java代码层面分析Java程序的性能, 无法从JVM, 系统甚至硬件层面找出性能的关键点. 而Linux系统层的perf, systemtap等工具能够查到磁盘IO, 网络IO, CPU, 内存等性能问题,但无法上达至Java层. 中间的这个断层使我们分析Java程序性能非常不便. 最近由演讲者开发的PerfJ可以让开发者从下自上地分析Java程序的性能. 演讲者将阐述perfj的原理, 举例怎么用perfj找到由于CPU cache miss引发的性能问题, 以及分析系统context switch造成的性能问题.

活动形式:微信群讨论(报名成功后获取入群二维码)

活动报名请按照如下格式发邮件到event@greenteajug.cn

姓名:XXX
电话号码:xxxxxxxxxxx
邮箱:xxxx@xxx.xxx
公司:xxxx有限公司
职位:xx工程师
Java使用年限:x年

系统的重构/The refactoring of system

作者:吴璞渊
视频:播放
View Fullscreen

Q&A
1、在日常工作中重构,会不会增加开发时间?
不会,即使增加也不会增加太多;只要运用合适的步骤对已有的方法分解、理解,一般都是比新写方法来的更快。因为重新写一遍实现,主体思路即使清楚,但是细节是不会全想到的,而很多细节的实现在已有代码里是现成的。
2、现有代码已经很混乱,也打算开始重构,需要做什么准备?
一般代码混乱,是由于业务场景、数据模型混乱开始的,应实现把这些重新设计好,再对代码重构。代码是为了实现这些而存在的,所以在代码重构前,有必要先理清楚业务场景和数据模型。
3、需要对code review做规范吗?
我也没确切的结论,只是以我的经验来看,不同人的侧重点不同,功能实现有很多方式,很难确定那一种更“好”,所以做到统一的规范太难。其二,规则定的太多,对于开发来说也是个负担。
4、对系统整体重构一次多长时间?
给个参考时间吧,对于每周发布一次的频率来看,“热度”高的代码重构完一般是4个月左右。
5、真的可以不需要测试吗?
测试的工作还是必不可少的,只是换了个方式和一个执行测试的人。加强单元测试是减少风险的手段之一,但是单元测试也不一定能解决所有问题,只是相对的。如果重构做完后,对现有的结构有了明确的划分,可以把系统做成配置化发布的形式,这样测试的工作就会大大减少了。