如何提升javacpu使用效率

jombowang1 贡献于2017-02-13

作者 p  创建于2016-11-07 03:28:00   修改者p  修改于2016-11-08 13:15:00字数3854

文档摘要:
关键词:

Java多核CPU性能检测 1.测试机型配置如下: 、 2.Cpu为4核 3.首先进行单线程测试,代码如下 3.1休眠时间 3秒 CPU资源监控器如下图。由于时间间隔太长,有些波动可能因为QQ(截图专用),浏览器,idea引起,看起来并不明显。持续一段时间观察,CPU0和CPU2正在运行,而CPU1和CPU3已经归位,也就说处于空闲状态。 3.2休眠时间 1秒 结果基本一致,在刚启动的时候,CPU都有一个上升的阶段,之后,CPU0和CPU3直在运行,CPU1和CPU2归位。 3.3无休眠时间 资源消耗会比较高,CPU会一直等待i这个资源就位。可以查看到,所有的CPU0-CPU4的使用率都达到一个比较高的峰值。 通过以上CPU曲线,可以分析出,在JAVA运行占用内存比较低的时候,会以单个CPU或者某几个CPU来执行。当占用内存比较高的时候,所有CPU统一运行来满足进程需求。 4多线程运行(同时开启五个线程) 4.1休眠时间3秒 与单线程的结果一样,除了刚开始运行CPU突然飙升之外,也是有两个CPU归位,另外两个CPU运行。因为是同时开启的五个线程,也就是说,在JVM内存使用不大情况下,CPU不会按照线程的数量进行CPU的分配。 4.2休眠时间1秒 可以看到,在并发执行时,可能会因为内存占用过高,会有3个CPU在使用状态。 4.3无休眠时间 CPU使用率也比较高,各个CPU都快达到峰值。说明与单线程一样,在内存使用过多的情况下,会分配到不同的CPU进行执行。 综合上面多线程和单线程测试,发现,java线程和CPU的使用并不是一一对应的关系,并不是开启多线程就能提高cpu使用效率。初步得出结论是按照内存使用率,自动分配cpu。 5.JAVA内存模型 通过上面的测试,想了解JAVA程序运行,应该先了解JAVA内存模型,查阅书籍<<深入了解JAVA虚拟机>>,(偷个懒,拍了照片,就不再一个字一个字的去敲了) 书中也没有提到,具体的调用使用CPU的方法,但是提出了一个观点: 1.对计算量相同的任务,程序线程并发协调的越有条不紊,效率自然就会越高;反之,线程之间频繁阻塞甚至死锁,将会大大降低程序的并发能力。 2.“让计算机并发执行若干个运算任务”与“更充分地利用计算机处理器的功能”之间的因果关系,并没有想象中的那么简单,其中一个重要的复杂性来源是绝大多数的运算任务都不可能只靠处理器“计算”就能完成,处理器至少要与内存交互,如读取运算数据、存储运算结果等,这个I/O操作是很难消除的。 3.高速缓存的存储交互很好的解决了处理器与内存的速度矛盾,但是也为计算机系统带来更高的复杂度,因为它引入一个新的问题:缓存一致性。 所以,cpu的使用是操作系统分配的。代码死锁,死循环可能导致的CPU使用过高。或者因为JVM中GC过于频繁,也就是新生代分配比例较小导致的GC频繁。 6CPU过高可能原因 我从网上查了一下CPU过高可能出现的原因。总结有以下几点 一、CPU过高 1、  us过高 使用监控工具快读定位哪里有死循环,大计算,对于死循环通过阻塞式队列解决,对于大计算,建议分配单独的机器做后台计算,尽量不要影响用户交互,如果一定要的话(如框计算、云计算),只能通过大量分布式来实现 2、  sy过高 最有效的方法就是减少进程,不是进程越多效率越高,一般来说线程数和CPU的核心数相同,这样既不会造成线程切换,又不会浪费CPU资源 二、内存消耗过高 1、  及时释放不必要的对象 2、  使用对象缓存池缓冲 3、  采用合理的缓存失效算法(还记得我们之前提到的弱引用、幽灵引用么?) 三、磁盘IO过高 1、  异步读写文件 2、  批量读写文件 3、  使用缓存技术 4、  采用合理的文件读写规则 四、网络 1、增加宽带流量 五、资源消耗不多但程序运行缓慢 1、使用并发包,减少锁竞争 2、对于必须单线程执行的使用队列处理 3、大量分布式处理 六、未充分利用硬件资源 1、  修改程序代码,使用多线程处理 2、  修正外部资源瓶颈,做业务拆分 3、  使用缓存 7总结排查CPU故障的方法和技巧 1、top命令:Linux命令。可以查看实时的CPU使用情况。也可以查看最近一段时间的CPU使用情况。 2、PS命令:Linux命令。强大的进程状态监控命令。可以查看进程以及进程中线程的当前CPU使用情况。属于当前状态的采样数据。 3、jstack:Java提供的命令。可以查看某个进程的当前线程栈运行情况。根据这个命令的输出可以定位某个进程的所有线程的当前运行状态、运行代码,以及是否死锁等等。 4、pstack:Linux命令。可以查看某个进程的当前线程栈运行情况。 8.多线程提高CPU使用方法 从网上搜集多线程提高CPU使用的方法 多核多cpu越来越普遍了,而且编写多线程程序也是件很简单的事情。在Windows下面,调用CreateThread函数一次就能够以你想要的函数地址新建一个子线程运行。然后,事情确实你发现创建多线程根本没有让程序快多少,也没有提高多少cpu利用率,甚至可能让cpu利用率下降。唯一能够确定的是多线程能够避免界面假死。为什么会是这样呢。   首先,讲一下多处理的一些知识,多处理器系统也只有一个待运行的线程队列,内存中也只有一个操作系统拷贝,而且也只有一个内存系统,但是会有多个cpu同时运行不同的线程。一个cpu运行一个线程,那么上图中的系统最多能在同一时间运行2个线程。其实,多处理系统需要掌握的知识不是这些,而是缓存一致性。   现在来解释下什么是缓存一致性。由于,还是只有一个内存系统。所有cpu都要和这个内存系统通信,但是只有一条总线,那么这无疑会造成总线紧张,限制整体的速度了。那么,你多个cpu也没多少意义了。解决这个问题的办法还是利用cpu的缓存机制,cpu的缓存命中率还是很高的,有90%以上吧。那么,继续利用缓存机制还是可以降低总线的频繁使用的。但是,每个cpu都有自己的缓存。如果有2个cpu的缓存存储的是同一内存数据的内容,其中一个cpu的缓存更新了,另外一个cpu的缓存也必须更新,这就是所谓的缓存一致性。编程多线程程序的一个很重要的一点就是避免因为缓存一致性引起的缓存更新风暴。   现在我举一个缓存更新风暴的例子。   锁lockHttp和lockSsl中间只有8个字节,而绝大部分系统上一个缓存行是128个字节,那么这2个锁很可能就处在同一个缓存行上面。那么,最坏的情况会发生什么事情了。假设处理器P1在运行一个处理http请求的线程T1,处理器P2在运行一个处理ssl请求的线程T2,那么当T1获得锁lockHttp的时候,锁的内容就会改变,为了保持缓存一致性, 就会更新P2的缓存。那么,T2要获得锁lockssl的时候,发现缓存已经失效了,就必须从内存中重新加载缓存之类。总之,这会将缓存命中率降低到90%以下,引起性能的严重降低。而且发生这种事情的原因是因为我们不了解硬件的体系结构。   多cpu不能成倍提高速度的原因是任务的某些部分是必须串行处理的。比如,矩阵乘法可以分为三个部分,初始化矩阵,相乘,返回结果。这三部分第二部分可以用多线程来处理,第一部分和第三部分则是不可以的。而且第二部分必须在第一部分完成之后,第三部分必须在第一部分完成之后。那么,无论你添加多少个处理器,最快的时间都至少是第一部分和第二部分的时间之和。这个事实好像叫做Amdahl法则。   如果使用多线程,那么就必须考虑线程同步,而线程同步又是导致速度降低的关键。所以下面就讲述一些方法来加快多线程程序的吞吐速度。   方法一,把一个任务分解为多个可以子任务。   因为总有些子任务是可以并发的,多个子任务并发执行了很可能就能够避免cpu需要io操作的完成了,而且能够提高系统的吞吐量。   方法二,缓存多线程的共享数据。   当你已经在使用多线程了,很多时候必须使用共享数据。如果,数据是只读的,那么可以在第一次获取后保存起来,以后就可以重复使用了。但是,第一次的获取还是无法避免的需要线程同步操作的。   方法三,如果线程数目有限,就不要共享数据。   做法是为每一个线程实例化一个单独的数据,其实就是为每一个线程分配一块数据使用。这样没有线程同步操作了,速度可以尽可能的提升。   方法四,如果没办法确定线程数目到底有多少,那么使用部分共享吧。   部分共享其实就是使用多个资源池代替一个资源池,资源池的数目得更加经验来确定。   最后在提一个叫做Thundering Herd的问题,该问题维基百科有定义http://en.wikipedia.org/wiki/Thundering_herd_problem。大意是,当多个线程在等待一个资源的时候,如果事件等待到了,操作系统是唤醒所有等待的线程让它们自己去竞争资源了还是选择一个线程把资源给它。当然唤醒所有的线程肯定开销要大,而且所有没有抢到资源的线程还得重新进入等待状态,这无疑造成很多没必要的操作,浪费了没必要的线程上下文切换。总之,会不会存在Thundering Herd还是跟不同的操作系统有关的。万一存在Thundering Herd了,多线程可能就没那么好办了。 个人总结 对于提高CPU使用效率,个人认为,在一般情况下,CPU应该都是在比较低的使用率中,不会达到预定峰值。可以通过根据项目性质设定jvm新生代,老年代所占比例。 而代码方面,在异步代码使用中,应该使用线程等手段,并发执行,提高CPU使用率,但是要防止死锁,死循环等代码出现。在并发达到一定数量是,CPU的使用过高是无可避免的,应该通过物理手段进行解决,而不完全依赖于代码层面。

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享文档获得金币 ] 1 人已下载

下载文档