我们的系统中新开发了一个数据抽取的功能,东西做完后,一看执行时间那叫一个恼火。参考同类系统同样功能的执行时间,目标:将本地数据处理时间压缩到5秒以内。

  第一步:

要想知道哪个地方需要优化,仅凭感觉还是不够,我使用btrace寻找速度慢点原因。下面贴出这次使用的btrace代码:

import static com.sun.btrace.BTraceUtils.name;
import static com.sun.btrace.BTraceUtils.print;
import static com.sun.btrace.BTraceUtils.println;
import static com.sun.btrace.BTraceUtils.probeClass;
import static com.sun.btrace.BTraceUtils.probeMethod;
import static com.sun.btrace.BTraceUtils.str;
import static com.sun.btrace.BTraceUtils.strcat;
import static com.sun.btrace.BTraceUtils.timeMillis; import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.Kind;
import com.sun.btrace.annotations.Location;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.TLS; /**
* 监控方法耗时
*
*/
@BTrace
public class PrintTimes { /**
* 开始时间
*/
@TLS
private static long startTime = 0; /**
* 方法开始时调用
*/
@OnMethod(clazz = "com.xxx.service.XXService", method = "/.+/")
public static void startMethod() {
startTime = timeMillis();
} /**
* 方法结束时调用<br>
*/
@SuppressWarnings("deprecation")
@OnMethod(clazz = "com.xxx.service.XXService", method = "/.+/", location = @Location(Kind.RETURN))
public static void endMethod() { print(strcat(strcat(name(probeClass()), "."), probeMethod()));
print(" [");
print(strcat("Time taken : ", str(timeMillis() - startTime)));
println("]");
}
}

本段代码会匹配 com.xxx.service.XXService 类中的所有方法,打印每个方法的执行时间,每调用一次会打印一次,不是总时间。更多BTrace内容请访问官网:https://kenai.com/projects/btrace

第二步到了这一步已经知道了速度慢集中在哪些点。对于这个系统我可以做哪些工作来优化呢?

1.代码方面调整
a.并行化 (关于线程池线程数量的调整,请参考我的另外一篇关于"设置最优线程数"的文章)
b.增加缓存
c.插入操作执行频繁的地方,用原生sql进行批量插入(持久化层使用EclipseLink)
d.避免大数据量表join操作
2.参数调整
a.JVM内存参数
b.数据库连接池参数 3.功能实现设计调整 (最不愿看到的)

根据实际情况采取相应手段调整。

第三步

检测优化后系统该功能性能情况,如果有效则保留,否则恢复代码到本次优化之前的那个状态。

第三步结束后,继续执行第一、二、三步。直到性能达到预期要求。

根据对待优化代码进行分析,最后采用了并行化,增加缓存以及批量插入优化的操作。软件参数和功能设计方面不需要调整。

--------------- 问题纪录 -------------

在将插入操作改成批量插入时,日志报以下错误:

Caused by: org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object
14:45:03.821 [pool-1-thread-2] ERROR java.lang.Throwable - at org.apache.tomcat.dbcp.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:114)
14:45:03.822 [pool-1-thread-2] ERROR java.lang.Throwable - at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
14:45:03.822 [pool-1-thread-2] ERROR java.lang.Throwable - at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:123)
14:45:03.822 [pool-1-thread-2] ERROR java.lang.Throwable - ... 39 more
14:45:03.823 [pool-1-thread-2] ERROR java.lang.Throwable - Caused by: java.util.NoSuchElementException: Timeout waiting for idle object

有几个思路:
1.数据库连接没有成功释放;(得到数据库连接池的监控数据,可以实时看到空闲连接的情况)
2.数据库连接成功释放,但是由于多个线程同时抢占连接而导致有些线程抢不到连接。(这个情况考虑增大数据库连接池) 

使用BTrace监控连接池发现只有获得连接没有释放连接操作,看来属于1。由于使用EclipseLink以为 entityManager.close()可以释放连接,经过查阅EclipseLink官网文档,原来是使用不当,下面是获取连接的详细信息,:

JPA 2.0
entityManager.getTransaction().begin();
java.sql.Connection connection = entityManager.unwrap(java.sql.Connection.class);
...
entityManager.getTransaction().commit();

最后在finally将connection.close()。


一次java性能调优总结的更多相关文章

  1. Java性能调优笔记

    Java性能调优笔记 调优步骤:衡量系统现状.设定调优目标.寻找性能瓶颈.性能调优.衡量是否到达目标(如果未到达目标,需重新寻找性能瓶颈).性能调优结束. 寻找性能瓶颈 性能瓶颈的表象:资源消耗过多. ...

  2. Java性能调优(一):调优的流程和程序性能分析

     https://blog.csdn.net/Oeljeklaus/article/details/80656732 Java性能调优 随着应用的数据量不断的增加,系统的反应一般会越来越慢,这个时候我 ...

  3. Java性能调优:利用JMC分析性能

    Java性能调优作为大型分布式系统提供高性能服务的必修课,其重要性不言而喻. 好的分析工具能起到事半功倍的效果,利用分析利器JMC.JFR,可以实现性能问题的准确定位. 本文主要阐述如何利用JMC分析 ...

  4. Java性能调优:利用JFR生成性能日志

    Java性能调优作为大型分布式系统提供高性能服务的必修课,其重要性不言而喻. 好的分析工具能起到事半功倍的效果,利用分析利器JMC.JFR,可以实现性能问题的准确定位. 本文主要阐述如何利用JFR生成 ...

  5. 第六章 Java性能调优工具(待续)

    Java性能调优工具 Windows工具 JDK命令行工具 JConsole工具 Visual VM多合一工具 Visual VM对QQL的支持 MAT内存分析工具 MAT对QQL的支持 JProfi ...

  6. java 性能调优和GC

    JAVA 性能调优和GC http://blog.csdn.net/gzh0222/article/details/7663181 JAVA GC调优手记 http://blog.csdn.net/f ...

  7. Java性能调优概述

    目录 Java性能调优概述 性能优化有风险和弊端,性能调优必须有明确的目标,不要为了调优而调优!!!盲目调优,风险远大于收益!!! 程序性能的主要表现点 执行速度:程序的反映是否迅速,响应时间是否足够 ...

  8. Java性能调优攻略全分享,5步搞定!(附超全技能图谱)

    对于很多研发人员来说,Java 性能调优都是很头疼的问题,为什么这么说?如今,一个简单的系统就囊括了应用程序.数据库.容器.操作系统.网络等技术,线上一旦出现性能问题,就可能要你协调多方面组件去进行优 ...

  9. Java性能调优实战,覆盖80%以上调优场景

    Java 性能调优对于每一个奋战在开发一线的技术人来说,随着系统访问量的增加.代码的臃肿,各种性能问题便会层出不穷. 日渐复杂的系统,错综复杂的性能调优,都对Java工程师的技术广度和技术深度提出了更 ...

  10. Java性能调优

    一.JVM内存模型及垃圾收集算法 1.根据Java虚拟机规范,JVM将内存划分为: New(年轻代) Tenured(年老代) 永久代(Perm) 其中New和Tenured属于堆内存,堆内存会从JV ...

随机推荐

  1. 解决Android与服务器交互大容量数据问题

    对于目前的状况来说,移动终端的网络状况没有PC网络状况那么理想.在一个Android应用中,如果需要接收来自服务器的大容量数据,那么就不得不考虑客户的流量问题.本文根据笔者的一个项目实战经验出发,解决 ...

  2. Unit01: JAVA开发环境

    Top JAVA开发环境 1. JAVA开发环境 1.1. 认识Linux操作系统 1.1.1. Linux的由来及发展 Linux起源于1991年,1995年流行起来,大家可以看到旁边的这个人,它就 ...

  3. Android 自定义ListView

    本文讲实现一个自定义列表的Android程序,程序将实现一个使用自定义的适配器(Adapter)绑定 数据,通过contextView.setTag绑定数据有按钮的ListView. 系统显示列表(L ...

  4. getPhysicalNumberOfCells 与 getLastCellNum的区别

    用org.apache.poi的包做excel导入,无意间发明若是excel文件中有空列,空列后面的数据全部读不到. 查来查去本来是HSSFRow供给两个办法:getPhysicalNumberOfC ...

  5. vue-cli安装失败问题

    1.尝试 管理员权限 安装,看是否能解决问题 2.仍未解决问题, 系统变量增加:  C:\Program Files\nodejs\node cache\node_modules\vue-cli\bi ...

  6. Mysql数据库的使用总结之ERROR 1146 (42S02)

    在使用mysql数据库过程中,遇到了错误ERROR 1146 (42S02):Table doesn't exist,经过了两天,终于解决了这个问题.引起该错误的原因不同,对应的解决方法也不同.这里只 ...

  7. jquery.serialize

    jQuery - serialize() 方法 serialize() 方法通过序列化表单值,创建 URL 编码文本字符串. serialize()函数用于序列化一组表单元素,将表单内容编码为用于提交 ...

  8. 性能调优利器之strace

    最近需要对一个自己开发的socket server的性能进行分析,刚开始还想了好长时间怎么来分析.后来才意识到其实使用strace就足够了. 观察到的现象是server单进程CPU使用率97,但磁盘i ...

  9. 我认识的log4j开源日志

    Log4j 在java中如何配置log4j!! 步骤: ①引入jar包,推荐新建一个lib文件夹,用来装所有的jar包(还要进行下图内的操作) 之后项目中就会多出一个引入外部Library的项目 ②创 ...

  10. 设置Beyond Compare 为 Git 默认的比较工具

    对于Beyond Compare4,Git版本号在2.2.0之后的,请在Git中依次输入以下命令: git config --global diff.tool bc3 git config --glo ...