扫码阅读
手机扫码阅读
性能测试中获取JVM资源信息
69 2024-04-13
在以往性能测试中,通常施压机的硬件资源不会成为压力瓶颈,但是在多任务并行的场景中,如果一个任务占用当前机器资源过多,会影响其他任务执行。或者当前用例本身存在问题,导致性能无法进一步提升,影响了性能测试执行。
根据以上场景,如果能从监控工程上得到解决自然是最好的。可以实时监控施压机和施压进程的CPU占用、内存使用、GC清空。但是,重点来了,并不是总能拥有一套完美的监控系统。这个时候,就需要自己手动解决一些痛点。
经过查阅资源,最终将方案锁定在java.lang.management.ManagementFactory
这个类,看名字和路径大概能猜个七七八八了。以上我提到的信息都可以调用这个类的API获取。
CPU使用率
下面分享一下如何获取当前JVM的CPU使用情况。
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
返回值着实让我很迷惑,至今还没懂其中奥妙。
下面分享获取系统负载的方法:
/**
* 获取系统一分钟内的平均load
* @return */ static def getLoad() {
osMxBean.getSystemLoadAverage() / getAvailableProcessors()
}
同样的问题也存在这个方法中,但目前使用比较少,就没有做修改。
获取GC信息
static List 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信息作为独立的依据。
其他
获取内存信息:
/**
* 获取堆内存信息
* @return */ static def heapMemInfo() {
memoryMXBean.getHeapMemoryUsage()
} /**
* 获取非堆内存信息
* @return */ static def noHeapMemInfo() {
memoryMXBean.getNonHeapMemoryUsage()
}
使用场景
目前我的使用场景主要2个:
在本地执行性能测试场景中,将JVM信息定期输出,包含在性能测试数据取样的功能中。 在服务执行性能测试场景中,将JVM信息作为一个资源调配的指标。例如:CPU资源占用过高,就降低一下对象池的活跃数据,主动回收一些资源。
在查阅资料的过程中,发现SDK的API很少能够直接获取硬件信息的,很多案例都是通过com.github.oshi:oshi-core:6.4.0
这个类库实现的。看了一下文档,功能非常强大,有兴趣的可以直接上这个。
原文链接:
http://mp.weixin.qq.com/s?__biz=MzU4MTE2NDEyMQ==&mid=2247498930&idx=1&sn=244cff327b72b02e0d21f5f6e8c815c3&chksm=fd497184ca3ef8926f7c70d4974baeff6bdbd20c181f276dd36be1a54794c127f88a59189b2e#rd
FunTester的其他文章
Selenium自动化的JUnit参数化实践
作为自动化测试人员,经常会遇到这样Selenium测试自动化场景:需要一次又一次地执行相同的测试用例,只是使用不同的输入和环境配置,从而使工作变得冗长且多余。
CompletableFuture实现异步转同步
在很早之前的文章服务端性能优化之异步查询转同步?
Groovy as关键字性能测试
之前写了文章介绍Groovy关键字as,我个人是十分推荐??
从手动测试到自动化测试(下)
前文说道从手动测试到自动化测试(上),接下来分?
物联网测试
在现在以及不远的未来家里的空调、冰箱房门可能有一个共同点:互联网连接。这种新现象被称为物联网。所有这些连接的硬件也由软件驱动的,这些软件应该经过软件测试。
加入社区微信群
与行业大咖零距离交流学习
软件研发质量管理体系建设
白皮书上线