java 测试线程_Java 线程(5)- 性能测试

264229b6d358

Ottawa, Canada by @marcojodoin

Avoid premature optimization. First make it right, then make it fast - if it is not already fast enough

衡量性能的指标

响应时间(Responsiveness),程序或服务对一个相关请求的相应时间

吞吐量(Throughout),程序或服务单位时间内可以完成的工作量

伸缩性(Scalability),当增加计算资源(如: CPUs, memory, storage, or I/O bandwidth)后, 可以提高多少吞吐量

Amdahl定理

Amdahl's law describes how much a program can theoretically be sped up by additional computing resources, based on the proportion of parallelizable and serial components.

math?formula=Speedup%5Cleq%5Cfrac%7B1%7D%7BF%20%2B%20%5Cfrac%7B(1%20-%20F)%7D%7BN%7D%7D

math?formula=Speedup :通过添加计算资源(如CPUs, memory),程序或应用可获得的加速速率

math?formula=F:程序或应用中不可并行化的部分所占的比率

math?formula=N:计算资源的数量

math?formula=N 无限大时,

math?formula=Speedup

math?formula=F 成反比, 也就是如果程序或应用中大部分是不可并行执行的,即使增加再多的计算资源, 程序的性能也不可能获得很大的提升。相反,如果程序中的任务完全可并行执行,即

math?formula=F%3D0(现实世界中,这样的程序是不存在的, 任何一个程序中都含有一些不可并行化的部分),那么

math?formula=Speedup%20%3D%20N,即可通过增加计算资源,来获得很大的性能提升。因此, 仔细的分析程序中不可并行化的部分(如一些隐含的不可并行的部分:从任务队列中取任务,计算结果的汇集,等)对性能提升是很重要的。

影响线程开销的因素

上下文切换(Context switching),线程的上下文切换是线程状态由 blocked 变为 running 或由 running 变为 blocked 的引起的,主要来自操作系统或JVM 对进程或线程调度的开销,过度的上下文切换会导致程序性能的低下,其中 IO 操作最容易引起上下文切换,因此应尽量分离 IO 操作,一个好的经验法则是,上下文切换的时间应该在 0.5 ms 到几微秒之间

内存同步(Memory synchronization),为了使内存同步,常用的方法要么串行化程序,而过度的串行化会影响程序的吞吐量,要么使用锁,而不当的加锁(不要担心正常的使用锁,JVM 对此已经优化的足够好了),可能带来锁竞争的问题,该问题不但影响程序的吞吐,同时还会影响程序的性能。影响锁竞争的因素包括:锁被请求的频率和锁被持有的时间,根据 Little 定律如果两者的乘积足够小,那么程序的性能会得到很好的提高,因此,可以改善程序的方法包括:

减小锁被持有的时间,即缩小锁的范围,快进快出,尽可能的缩小 synchronized 块的范围,尤其是在保证程序正确的情况下, 尝试把计算和阻塞(如I/O)操作移出 synchronized 块

减小锁被请求的频率,如对不相关的独立状态变量,用不同的锁进行守护、尝试将一个容器(如:ConcurrentHashMap)进行拆分,然后使用不同的锁对拆分后的片段进行守护, 但该技术有一定的副作用,如:很难对整个容器进行加锁,因此可能在一定程度上带来可见性的问题、避免在频繁调用的代码上加锁和避免使用排他锁(Exclusive Locks)

阻塞(Blocking),主要来自对资源、锁或 I/O 的竞争

测试

The goal of testing is not so much to find errors as it is to increase confidence that the code works as expected

制定测试计划

What do you mean by "faster"? (预期)

Under what conditions will this approach actually be faster? Under light or heavy load? With large or small data sets? Can you support your answer with measurements? (条件)

How often are these conditions likely to arise in your situation? Can you support your answer with measurements? (测量)

Is this code likely to be used in other situations where the conditions may be different? (环境)

What hidden costs, such as increased development or maintenance risk, are you trading for this improved performance? Is this a good trade off? (隐含的代价)

测试的方法

基本的单元测试(保证基本的功能正确)

测试阻塞操作(设定等待时间->中断->Thread.join())

构造测试程序与数据(问题集中在如何验证测试数据? 如何提高测试程序的并发性? 如何跟踪线程)

测试内存泄露(可以使用 profile 工具)

性能测试

避免测试中的陷阱

GC,要求运行测试的时间足够长,以保证 JVM 有 GC 的发生

动态编译,同样要求运行测试的时间足够长,即 JVM 的预热,并且应该舍去第一运行的数据

关注 JVM 对代码的优化,主要集中在两个方面,一是测试程序对代码的覆盖率,另一个是避免 JVM 将一些测试基准当做 dead code 优化掉, 要求测试总在 -server 下运行

尽量的模仿实际情况

分析测试结果

CPU 是否被均匀的使用,如:一些 CPU 负载高,而另一些负载低,这说明大多数计算集中在某一(某些)线程(集合)中, 因此需要加强程序的并行化

CPU 是否被充分的使用,如:负载不够,I/O 限制,外部限制(如:数据库,web service等),锁竞争,可以使用 profiler 来分析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值