您好,欢迎访问三七文档
性能优化经验分享丁伟建陈哲缪诚敏宋孝东2015.01.04目录Java性能优化原则Java代码性能相关(项目发现)Java性能优化原则Java代码的性能,简单的说体现在,系统运行是否流畅,用户交互是否迅速等表面现象,深层次来讲,也就是通过吞吐率等指标来体现,那么到底什么事影响Java代码性能的根本原因?一般来说可以归为两个方面:代码运算性能内存使用代码运算性能代码运算性能主要指:同样完成一个任务,用来实现的代码,是否高效,是否简洁例子1:数组的copypublicstaticvoidcopyBySystem(){int[]a={1,2,3,4,5};int[]b=newint[5];System.arraycopy(a,0,b,0,a.length);}publicstaticvoidcopyBySelf(){byte[]c={'a','b','c','d','e'};byte[]d=newbyte[5];for(inti=0;i5;i++){d[i]=c[i];}}数组CopycopyBySelfcopyBySystem代码经过编译后,使用的命令越少一般就是更高效的运算逻辑其他一些运算性能的例子选择合适的集合不同的集合有不同的特点,分别适合不同的场合ArrayList,LinkedList,HashMap,Hashtable,ConcurrentHashMap等乘除使用移位运算符在Java代码中对于乘除运算,直接使用移位运算符,肯定是更高效的一种方式(直接1,0操作),java.Math包使用已有的框架方法在实现代码时,尽量选择JDK自带API的一些方法来实现功能,或者一些成熟的开源框架提供的API一般JDK的API方法都是通过相对高效的算法来实现的,一些特殊功能可能使用了native方法,将会运行效率更高Java内存模型Java垃圾回收简介JVM的内存结构分代回收默认的回收机制Java内存影响Java程序性能的最主要一个原因就是:垃圾回收当Java程序进行垃圾回收的时候,会造成STW,整个应用将会完全暂停,直到回收完成;所以一般来说垃圾回收的频率越小,次数越少越好;如何做到这一点呢?要从代码编写的方方面面去思考这个问题:对象的分配:Strings=newString(“s”);Strings=“s”;少建对象,缩小对象作用域尽量使用基本类型对于static,final对象的创建集合的大小控制Java代码基于性能方法的内联(final)重复计算及请求循环的处理异常的控制资源管理(文件,连接池,线程)IO处理(文件IO,数据库IO)缓存处理合理的使用框架重复循环谨慎对待循环的处理避免过于循环嵌套避免循环调用sql避免循环逻辑太过复杂真正的重复动作才用循环循环异常异常的开销很大不要有空异常捕获避免使用异常处理业务异常线程线程的开销线程管理线程相关的设计数据库IO数据库设计数据库框架短连接,少操作原则缓存应用缓存系统内部实现分布式缓存memcached框架开源框架不是完美曾经碰到的一个hibernate的问题:selectorderentit0_.ORDER_IDasORDER1_44_,RECO49_44_,fromORDER_INFO_DATEorderentit0_whereorderentit0_.CUST_ID=10020302andorderentit0_.OPER_DATE=?andorderentit0_.OPER_DATE=?andorderentit0_.STATUS?andorderentit0_.STATUS?orderbyorderentit0_.OPER_DATEdescHibernate-entityManager-4.2.1LiteralExpression类selectorderentit0_.ORDER_IDasORDER1_44_,RECO49_44_,fromORDER_INFO_DATEorderentit0_whereorderentit0_.CUST_ID=?andorderentit0_.OPER_DATE=?andorderentit0_.OPER_DATE=?andorderentit0_.STATUS?andorderentit0_.STATUS?orderbyorderentit0_.OPER_DATEdesc常用的JVM参数类型参数运行模式-sever整个堆内存大小为-Xms和-Xmx设置相同的值。新生代空间大小-XX:NewRatio:2到4.-XX:NewSize=?–XX:MaxNewSize=?.使用NewSize代替NewRatio也是可以的。持久代空间大小-XX:PermSize=256m-XX:MaxPermSize=256m.设置一个在运行中不会出现问题的值即可,这个参数不影响性能。GC日志-Xloggc:$CATALINA_BASE/logs/gc.log-XX:+PrintGCDetails-XX:+PrintGCDateStamps.记录GC日志并不会特别地影响Java程序性能,推荐你尽可能记录日志。GC算法-XX:+UseParNewGC-XX:+CMSParallelRemarkEnabled-XX:+UseConcMarkSweepGC-XX:CMSInitiatingOccupancyFraction=75.一般来说推荐使用这些配置,但是根据程序不同的特性,其他的也有可能更好。发生OOM时创建堆内存转储文件-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=$CATALINA_BASE/logs发生OOM后的操作-XX:OnOutOfMemoryError=$CATALINA_HOME/bin/stop.sh或-XX:OnOutOfMemoryError=$CATALINA_HOME/bin/restart.sh.记录内存转储文件后,为了管理的需要执行一个合适的操作。目录性能瓶颈优化方向数据库服务器集群JAVA端优化SQL现在大部分项目使用了Hibernate,MyBatis等框架对数据库进行了封装。造成代码在coding的时候远离SQL。好处是开发快速,代码可控。但是在用不合理的情况下,缺点就很容易暴露出来。1.过多的使用级联。造成简单的查询功能复杂话,数据冗余。2.在执行复杂逻辑的时候,往往逻辑层在JAVA端实现,调用太多的简单SQL,反而减慢了代码的效率。3.在代码开发时不用写SQL,也就缺少了SQL优化,造成SQL查询的时候效率低下。性能瓶颈网络:是否存在不稳定现象存储器IO:检查服务器的IO是否存在异常内存:检查服务器物理内存和交换内存的使用情况CPU:检查CPU的利用率逻辑算法:算法的调整涉及到设计的修改,牵涉到的面比较广,有时候可能导致架构的变更,如表结构、计算方法等。SQL语句:SQL写的不好,没有使用数据的特性。SQL执行时间解析执行返回SQL解析流程SQL解析DDL语句(数据定义语言),他们是从来不会共享使用的,也就是每次执行都需要进行硬解析。CREATE,DROP,ALTERDML语句(数据操纵语言),他们会根据情况选择要么进行硬解析,要么进行软解析。INSERT,UPDATE,DELETE,SELECTSQL执行执行计划SQL执行自下而上的顺序解析WHERE子句表之间的连接写在其他WHERE条件之前,可以过滤掉最大数量记录的条件写在WHERE子句的末尾优化前:SELECT*FROMORDER_INFO_DATEWHEREEMP_ID=111ANDCREATE_DATESYSDATE-100优化后:SELECT*FROMORDER_INFO_DATEWHERECREATE_DATESYSDATE-100ANDEMP_ID=111结果返回判断条件尽量在SQL语句中体现返回的结果集尽量最小按场景多Entity配置尽量少的级联索引的使用以空间换时间过多的索引会增加INSERT、DELETE、UPDATE的负担不必要的索引尽量删除存在空值的字段尽量不要创建索引索引可能失效的原因:•对索引字段进行计算操作•在索引列上出现数据类型转换•在索引列上使用ISNULL和ISNOTNULL•在索引字段上使用not,,!=•在索引字段上使用like‘%%’索引的使用索引的使用索引的使用MYSQL子查询的问题数据库集群(Rac)数据库集群(Mysql)延时读写分离Or横纵切分?读写分离纵横切分优点1.增加一定的可扩展性2.增加冗余3.增加了机器的处理能力(硬件资源增加了)4.对于读操作为主的应用,效果比较好1.没有延时问题2.根据功能模块切分,数据间独立3.数据块小,速度快4.事务处理相对简单缺点1.服务器之间延时2.扩展能力有限3.写服务会成为系统的风险点1.代码编写前需要考虑2.维护的时候可能需要跨库Nginx性能优化多进程处理设置请求头和请求体缓存大小开启文件缓存压缩静态响应资源控制响应时间Linux内核优化添加FastCGI_Cache缓存动态内容多进程处理多进程,大家应该都了解,这里不多介绍,nginx在性能优化上也要采用多进程处理,提高处理能力和响应速度设置工作的进程数设置项worker_processes该项一般根据CPU的个数决定,一般等于或者倍数于CPU的个数设置单个进行处理的连接数worker_rlimit_nofile每个进程打开的文件个数,与机器ulimit-n保持一致worker_connections单个进程打开的连接数,小于等于nginx用户打开的文件个数worker_cpu_affinity设置进程与cpu有的亲和力,可以讲worker绑定到具体CPU上,减少资源的竞争worker_cpu_affinity00000001000000100000010000001000000100000010000001000000;设置请求头和请求体的缓存大小请求头和请求体的大小,决定了请求信息是否会存入临时文件,当请求信息大于设定的大小时,会将部分请求信息存储到临时文件,这样无形中增加了硬盘的IO操作,在高并发环境中,我们尽量减少对硬盘的IO操作,具体值根据项目配置和调整如下:client_header_buffer_size128k;large_client_header_buffers4128k;client_body_buffer_size128k;client_max_body_size256k;Access_log;Error_logtcp_nopush;tcp_nodelay开启文件缓存缓存的意义:缓存的意义大家都知道,Nginx中同样可以设置打开的文件缓存,避免文件的重复加载具体配置如下:open_file_cachemax=1024inactive=20s;为打开的文件制定缓存open_file_cache_valid30s;30s检查一次缓存信息open_file_cache_min_uses1;缓存中文件的最少使用次数压缩静态资源开启压缩功能,减少访问的带宽,在高并发下提升访问量和响应速度Nginx的压缩方式(gzip)gzipon;gzip_min_length1k;gzip_buffers416k;gzip_http_version1.0;gzip_comp_level2;gzip_typestext/plainapplication/x-javascripttext/cssapplication/xml;gzip_varyon;控制连接时间控制连接时间,主要是防止一些请求或响应的时间过程,长时间占用TCP连接资源不放,影响其他正常的请求和响应Nginx配置如下:keepalive_timeout60;(根据业务调整,一般建议15-20)补充Nginx作为反向代理服务器,建议将图片服务器和静态资源服
本文标题:性能优化经验分享
链接地址:https://www.777doc.com/doc-2396088 .html