我们的系统中新开发了一个数据抽取的功能,东西做完后,一看执行时间那叫一个恼火。参考同类系统同样功能的执行时间,目标:将本地数据处理时间压缩到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. [转]Linux/Ubuntu sudo不用输入密码的方法

      通常我们并不以root身份登录,但是当我们执行某些命令 (command)时需要用到root权限,我们通常都是用"sudo command"来执行command.由于使用Ubu ...

  2. Easy Tag Write(3.1)

    package skyseraph.android.util; import skyseraph.easytagwrite.R; import android.app.Dialog; import a ...

  3. 自由缩放属性resize

    为了增强用户体验,CSS3增加了很多新的属性,其中resize就是一个重要的属性,它允许用户通过拖动的方式来修改元素的尺寸来改变元素的大小.到目前为止,可以使用overflow属性的任何容器元素. 在 ...

  4. UIAlertController警告视图和操作表单

    //创建一个myAlert1操作表单对象(UIAlertControllerStyleActionSheet为操作表单,UIAlertControllerStyleAlert为警告视图) UIAler ...

  5. jquery jQuery-File-Upload 例子

    网上jquery-file-upload的例子 都过于简单,在项目中这个插件经常使用,写个例子供参考. 下面介绍 用插件实现图片异步上传的代码. 1   比要的js一个都不能少,他们之间是有依赖关系的 ...

  6. 【003:switch 不加 break的结果

    #include <stdio.h> int main(){ char ch = 's'; switch(ch){ case 'a':{ printf("aaaaa") ...

  7. 渗透日记-POST注入

    今晚给一个网站做了一次入侵检测,首先进行信息刺探后,发现这个站有注入策略,所有页面都没法通过常规的注入,利用wvs扫描网站发现一个页面. 这个页面直接暴露出了错误信息,看了一下url没有参数却爆出了错 ...

  8. iOS 多语言的切换

    一.添加应用程序需要支持的国际语言 二.新建一个Localizable.strings文件,作为多语言对应的词典,存储多种语言 三.在Localizable.strings的对应文件以键值对的形式配置 ...

  9. mybatis,sql 批量更新

    <update id="update81OrderStatus" parameterType="java.util.Map">    update ...

  10. TortoiseGit使用手册

    1 安装 1.1 32位系统 1.2 64位系统 2 配置 2.1 设置语言 2.2 配置用户信息 2.3 生成ssh-key(仅限第一次使用) 2.4 初始化仓库(尚未使用git管理的项目) 2.5 ...