前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >性能测试中获取JVM资源信息

性能测试中获取JVM资源信息

作者头像
FunTester
发布于 2023-02-23 02:39:13
发布于 2023-02-23 02:39:13
76400
代码可运行
举报
文章被收录于专栏:FunTesterFunTester
运行总次数:0
代码可运行

在以往性能测试中,通常施压机的硬件资源不会成为压力瓶颈,但是在多任务并行的场景中,如果一个任务占用当前机器资源过多,会影响其他任务执行。或者当前用例本身存在问题,导致性能无法进一步提升,影响了性能测试执行。

根据以上场景,如果能从监控工程上得到解决自然是最好的。可以实时监控施压机和施压进程的CPU占用、内存使用、GC清空。但是,重点来了,并不是总能拥有一套完美的监控系统。这个时候,就需要自己手动解决一些痛点。

经过查阅资源,最终将方案锁定在java.lang.management.ManagementFactory这个类,看名字和路径大概能猜个七七八八了。以上我提到的信息都可以调用这个类的API获取。

CPU使用率

下面分享一下如何获取当前JVM的CPU使用情况。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    static ThreadMXBean threadBean = ManagementFactory.getThreadMXBean()

    static OperatingSystemMXBean osMxBean = ManagementFactory.getOperatingSystemMXBean()

    static long lastSysTime = System.nanoTime()

    static long lastUserTime = 0
    
    /**
     * 获取最大进程数N,CPU使用率N*100%
     * @return
     */
    static int getAvailableProcessors() {
        osMxBean.getAvailableProcessors()
    }

    /**
     * 获取当前线程CPU使用率,最大100
     * 已乘以100,已经除以了系统最大进程数
     * @return
     */
    static double getCpuUsage(boolean avg = true) {
        long totalTime = 0
        for (long id : threadBean.getAllThreadIds()) {
            totalTime += threadBean.getThreadCpuTime(id)
        }
        long curtime = System.nanoTime()
        long usedTime = totalTime - lastUserTime
        long totalPassedTime = curtime - lastSysTime
        lastSysTime = curtime
        lastUserTime = totalTime
        def d = avg ? (((double) usedTime) / totalPassedTime / getAvailableProcessors()) * 100 : (((double) usedTime) / totalPassedTime) * 100
        return d > 100 ? 8.88 : d
    }

这里我用了一个参数,用来区分是否返回平均使用率还是返回总使用率之和。因为在docker环境中com.funtester.utils.OSUtil#getAvailableProcessors返回值着实让我很迷惑,至今还没懂其中奥妙。

下面分享获取系统负载的方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    /**
     * 获取系统一分钟内的平均load
     * @return
     */
    static def getLoad() {
        osMxBean.getSystemLoadAverage() / getAvailableProcessors()
    }

同样的问题也存在这个方法中,但目前使用比较少,就没有做修改。

获取GC信息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

    static List<GarbageCollectorMXBean> gcMxBeans = ManagementFactory.getGarbageCollectorMXBeans();

    /**
     * 获取GC信息{@link com.funtester.utils.OSUtil.GCInfo}
     * @return
     */
    static def getGCinfo() {
        def infos = []
        for (GarbageCollectorMXBean gcMxBean : gcMxBeans) {
            infos << new GCInfo(gcMxBean)
        }
        infos
    }

    /**
     * GC信息类
     */
    static class GCInfo extends AbstractBean {

        String name

        int count

        int time

        GCInfo(String name, int count, int time) {
            this.name = name
            this.count = count
            this.time = time
        }

        GCInfo(GarbageCollectorMXBean gcMxBean) {
            this.name = gcMxBean.getName()
            this.count = gcMxBean.getCollectionCount()
            this.time = gcMxBean.getCollectionTime()
        }

    }

这里只能算是个输出,很少用GC信息作为独立的依据。

其他

获取内存信息:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    /**
     * 获取堆内存信息
     * @return
     */
    static def heapMemInfo() {
        memoryMXBean.getHeapMemoryUsage()
    }

    /**
     * 获取非堆内存信息
     * @return
     */
    static def noHeapMemInfo() {
        memoryMXBean.getNonHeapMemoryUsage()
    }

使用场景

目前我的使用场景主要2个:

  1. 在本地执行性能测试场景中,将JVM信息定期输出,包含在性能测试数据取样的功能中。
  2. 在服务执行性能测试场景中,将JVM信息作为一个资源调配的指标。例如:CPU资源占用过高,就降低一下对象池的活跃数据,主动回收一些资源。

在查阅资料的过程中,发现SDK的API很少能够直接获取硬件信息的,很多案例都是通过com.github.oshi:oshi-core:6.4.0这个类库实现的。看了一下文档,功能非常强大,有兴趣的可以直接上这个。

FunTester原创专题推荐~

-- By FunTester

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • CPU使用率
  • 获取GC信息
  • 其他
  • 使用场景
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文