前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >性能测试之java程序观察简单步骤

性能测试之java程序观察简单步骤

作者头像
高楼Zee
发布2019-11-14 17:11:36
7950
发布2019-11-14 17:11:36
举报
文章被收录于专栏:7DGroup7DGroup7DGroup

背景

在做性能测试中不断思考java应用,性能怎么观察,怎么通过方法定位到代码,是否有通用步骤,通过查找资料与查看网上知识、帮助文档之后,才有如下文章,话说知道不等于会,会不等于能运用,只有不断有意识去练习才能掌握。

操作步骤

  • 使用TOP命令找到谁在消耗CPU比较高的进程,例如pid = 1232
  • 使用top -p 1232 单独监控该进程
  • 输入大写的H列出当前进程下的所有线程
  • 查看消耗CPU比较高的线程,并看线程编号,例如 12399
  • 使用jstack 1232>pagainfo.dump 获取当前进程下的dump线程信息
  • 将第四步获取的线程编号12399转换成16进制306f (printf "%x\n" 12399)
  • 根据306f在第5步获取的栈信息中查找tid=0x306的线程
  • 定位代码位置(根据打印出来的堆栈信息查看代码所在位置)

注意:从操作系统打印出的虚拟机的本地线程看,本地线程数量和Java线程堆栈中的线程数量相同, 说明二者是一一对应的。只不过java线程中的nid中用16进制来表示, 而本地线程中的id用十进制表示。

DEMO演示

使用虚拟机演示:

使用top命令查看目前操作系统性能情况:

使用idea编写简单的demo进行演示通过进程到线程定位到代码行:

import com.sdgroup.pojo.StudentInfo;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author liwen
 * @Title: PageIndex
 * @Description: 使用命令top-->top -p PID  -- H   jstack pid
 * @date 2019/11/9 / 10:23
 */
@Log4j2
@Controller
public class PageIndexController {


    /**
     * 测试demo
     * @return
     */
    @GetMapping("/7d")
    @ResponseBody
    public Object topDemo() {
        StudentInfo stInfo = new StudentInfo();
        stInfo.setName("topJava");
        stInfo.setAge(30);
        stInfo.setDes("冠礼之年测试java通过top命令查看jvm");
        stInfo.setGrade("7DGroup");

        for (int i = 0; i < 100000; i++) {
            i++;
            try {
                log.info("my is print" + i);
                Thread.sleep(i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return stInfo;
    }

    /**
     * 调试
     * @return
     */
    @GetMapping("/7ddemo")
    @ResponseBody
    public Object topDemo1() {
        StudentInfo stInfo = new StudentInfo();
        stInfo.setName("topJava");
        stInfo.setAge(30);
        stInfo.setDes("冠礼之年测试java通过top命令查看jvm");
        stInfo.setGrade("7DGroup");

        return stInfo;
    }
}

打开浏览器访问:

访问写好的请求http://ip:port/7d并且通过工具进行访问,通过查看日志显示系统后台运行,前端一直处于等待状态

可以使用jmeter或者idea等工具进行不断访问显示,方便咱们进行性能定位:

也可以使用idea简单发起请求:

点击请求:

打开linux系统,再次打开窗口中敲top命令查看消耗CPU中的java进程,通过观察该进程在操作系统中消耗cpu不是很高,但是为了演示上面操作步骤,咱们暂时使用该进程进行演示:

使用命令top -p PID即可看到该进程下的线程信息

再次使用:jsack 命令进行,打出dump信息

如果执行没有该命令需要找到jdk安装目录执行:

可以参考:https://www.cnblogs.com/lossingdawn/p/10856199.html

[root@localhost bin]#

[root@localhost bin]# ./jstack 93114 >/home/7d/7djava.dump

[root@localhost bin]#

切换到dump生成的目录下:

可以下载到本地进行查看或者使用jdk自带的jvisualvm工具查看:

目前使用文本查看方式

[root@localhost 7d]# vim 7djava.dump

显示信息

发现该进行消耗多,其实也不多,目前是为演示所以暂时使用下。

转换:十进制转换16进制:

在打开dump文件中通过vim搜索命令查找:

从上面可以看出目前线程正处于TIMED_WAITING状态,表示当前被挂起一段时间,时长为参数中指定的时长,如Thread.sleep(1000)。因此该线程当前不消耗CPU。

找到代码的包名与代码行:

从下面信息得出:

再次查看源码:

总结:

通过压力工具稳定发压,使用原始命令top查看java进程再通过jstack pid>inof.dump命令打出线程信息,通过top -p pid查看线程,通过判断那个线程消耗cpu,再次通过转换为16进制进程定位到代码。

在实际工作中该方法,经常用于线上定位问题,因为线上机器不能安装其他工具,如果是线下测试其实有很多工具可以使用(Jprofiler、jmc、jvisualvm)等工具。

下面简单介绍下线程怎么看:

"http-nio-8080-exec-11" #30 daemon prio=5 os_prio=0 tid=0x00007fadf8001000 nid=0x16bf8 waiting on condition [0x00007fae6c7d0000]

  1. 线程名称:"http-nio-8080-exec-11"
  2. 线程优先级:prio=5
  3. 线程对应的本地线程id号:nid=0x16bf8
  4. 线程的状态:waiting
  5. 线程占用内存地址:[0x00007fae6c7d0000]

光知道上面内容咱们做性能测试还是不知怎么下手?其实咱们通过线程分析知道程序他目前处于什么状态,就知道怎么下手分析,你说呢?。

在分析之前需要了解线程生命周期还得知道谁消耗资源。

线程整个生命周期,可以分为五个阶段,分别是新建状态New、就绪状态Runnable、运行状态Running、阻塞状态Blocked和死亡状态Terminated;

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 7DGroup 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 操作步骤
  • DEMO演示
  • 总结:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档