计数器、WMI

获取设备的内存信息,如系统可用运行内存:

 1     public static async Task<double> GetMemoryAvailableAsync(FileSizeUnit fileSizeUnit = FileSizeUnit.GB)
2 {
3 return await Task.Run(() =>
4 {
5 using var managementClass = new ManagementClass("Win32_PerfFormattedData_PerfOS_Memory");
6 using var instances = managementClass.GetInstances();
7 double available = 0;
8 foreach (var mo in instances)
9 {
10 //AvailableMBytes单位是MB
11 var size = long.Parse(mo.Properties["AvailableMBytes"].Value.ToString()) * 1024 * 1024;
12 available += size.ConvertTo(fileSizeUnit);
13 }
14
15 return available;
16 });
17 }

以上是ManagementClass方式实现,还有ManagementObjectSearcher,都是WMI检索查询。

WMI查询比较慢,上面一段耗时在200ms+。

还有一种用的较多的,PerformanceCounter性能计数器,以CPU获取为例:

 1     public static async Task<double> GetUsageByCounterAsync()
2 {
3 //CPU计数器
4 using var pcCpuUsage = new PerformanceCounter("Processor", "% Processor Time", "_Total") { MachineName = "." };
5 // NextValue首次会返回0,所以需要加个延时下次再获取值
6 pcCpuUsage.NextValue();
7 await Task.Delay(TimeSpan.FromMilliseconds(500));
8 var cpuUsed = pcCpuUsage.NextValue();
9 return cpuUsed;
10 }

性能计数器,也有一定的耗时40ms以上。另外因为它实现方式,初始化后无法第一次获取到真正数值,需要间隔一段时间再去拿。所以此方案实际耗时挺高

WMI、性能计数器,昨天遇到了使用异常:

看源码,计数器是注册表PerformanceData位置损坏了,而Management是IWbemServices获取状态码ErrorCode异常。

PerformanceCounter是WMI,而WMI是基于WBEM协议实现的,所以我理解成上面的异常其实是一类问题。

官网有对此类异常有一些描述:重新生成性能计数器库值 - Windows Server | Microsoft Learn

所以基于PerformanceCounter、ManagementClass以及ManagementObjectSearcher的实现,有一定风险。

kernel32

kernel32下有个函数可以获取内存状态

1     [DllImport("kernel32.dll")]
2 [return: MarshalAs(UnmanagedType.Bool)]
3 static extern bool GlobalMemoryStatusEx(ref MEMORYINFO mi);

以下是获取可用运行内存的实现:

    //Define the information structure of memory
[StructLayout(LayoutKind.Sequential)]
struct MEMORYINFO
{
public uint dwLength; //Current structure size
public uint dwMemoryLoad; //Current memory utilization
public ulong ullTotalPhys; //Total physical memory size
public ulong ullAvailPhys; //Available physical memory size
public ulong ullTotalPageFile; //Total Exchange File Size
public ulong ullAvailPageFile; //Total Exchange File Size
public ulong ullTotalVirtual; //Total virtual memory size
public ulong ullAvailVirtual; //Available virtual memory size
public ulong ullAvailExtendedVirtual; //Keep this value always zero
} /// <summary>
/// Get the current memory usage
/// </summary>
/// <returns></returns>
private static MEMORYINFO GetMemoryStatus()
{
MEMORYINFO memoryInfo = new MEMORYINFO();
memoryInfo.dwLength = (uint)System.Runtime.InteropServices.Marshal.SizeOf(memoryInfo);
GlobalMemoryStatusEx(ref memoryInfo);
return memoryInfo;
}
/// <summary>
/// 获取系统可用运行内存
/// </summary>
/// <param name="fileSizeUnit">默认单位GB</param>
/// <returns></returns>
public static double GetMemoryAvailable(FileSizeUnit fileSizeUnit = FileSizeUnit.GB)
{
var memoryStatus = GetMemoryStatus();
var memoryAvailable = ((long)memoryStatus.ullAvailPhys).ConvertTo(fileSizeUnit);
return memoryAvailable;
}

上述方式,获取速度超快,几乎不耗时。

通过Kernel32-GetSystemTimes方式,获取CPU信息(CPU比例计算逻辑,代码略多点):

 1     /// <summary>
2 /// 获取CPU占用率/使用率(单位:%)
3 /// </summary>
4 /// <returns></returns>
5 public static async Task<double> GetUsageByKernelAsync()
6 {
7 long idleTime1 = 0;
8 long kernelTime1 = 0;
9 long userTime1 = 0;
10 if (GetSystemTimes(out var lpIdleTime, out var lpKernelTime, out var lpUserTime))
11 {
12 idleTime1 = lpIdleTime;
13 kernelTime1 = lpKernelTime;
14 userTime1 = lpUserTime;
15 }
16 //添加俩次获取CPU信息的间隔
17 await Task.Delay(TimeSpan.FromSeconds(0.5));
18 long idleTime2 = 0;
19 long kernelTime2 = 0;
20 long userTime2 = 0;
21 if (GetSystemTimes(out var lpIdleTime2, out var lpKernelTime2, out var lpUserTime2))
22 {
23 idleTime2 = lpIdleTime2;
24 kernelTime2 = lpKernelTime2;
25 userTime2 = lpUserTime2;
26 }
27 //分别获取到用户时间、内核时间、空闲时间
28 var userTime = userTime2 - userTime1;
29 var kernelTime = kernelTime2 - kernelTime1;
30 var idleTime = idleTime2 - idleTime1;
31 //计算Cpu占用率。计算公式:用户时间+内核时间-空闲时间/用户时间+内核时间
32 var systemTotal = kernelTime + userTime;
33 var cpu = (systemTotal - idleTime) * 10000 / systemTotal;
34 return cpu / 100.0;
35 }
36
37 /// <summary>
38 /// 获取系统CPU时间数据
39 /// </summary>
40 /// <param name="lpIdleTime">空闲时间</param>
41 /// <param name="lpKernelTime">内核时间</param>
42 /// <param name="lpUserTime">用户时间</param>
43 /// <returns></returns>
44 [DllImport("kernel32.dll", SetLastError = true)]
45 static extern bool GetSystemTimes(out long lpIdleTime, out long lpKernelTime, out long lpUserTime);

另外,也有一种途径可以获取到内存信息,引用程序集Microsoft.VisualBasic,Microsoft.VisualBasic.Devices下有个ComputerInfo类

var physicalMemory = new Microsoft.VisualBasic.Devices.ComputerInfo().AvailablePhysicalMemory;

可以拿到可用内存、总内存,不过CPU信息是没有的。

ComputerInfo的内部源码,我标注了下:

所以ComputerInfo,也是基于GlobalMemoryStatusEx函数做了封装,大家可以直接用。

关键字:【Kernek32-GlobalMemoryStatusEx】【Kernek32-GetSystemTimes】

参考列表:

C# 几种获取电脑内存、CPU信息的方案的更多相关文章

  1. MD5做为文件名。机器唯一码有电脑的CPU信息和MAC地址,这两个信息需要在linux或unix系统下才能获取吧。

    可以采用机器(电脑)唯一码 + 上传IP + 当前时间戳 + GUID ( + 随机数),然后MD5做为文件名.机器唯一码有电脑的CPU信息和MAC地址,这两个信息需要在linux或unix系统下才能 ...

  2. C#获取电脑的相关信息

    /* 创建者:菜刀居士的博客  * 创建日期: 2014年08月31号  * 功能:获取电脑的相关信息  *  */ namespace Net.String.ConsoleApplication { ...

  3. python获取系统内存占用信息的实例方法

    psutil是一个跨平台库(http://code.google.com/p/psutil/),能够轻松实现获取系统运行的进程和系统利用率(包括CPU.内存.磁盘.网络等)信息.它主要应用于系统监控, ...

  4. C#程序中获取电脑硬件配置信息的一种方法

    本文介绍获取cpu信息和内存信息的方法,根据本文所举例的代码可以举一反三获取更多信息. 获取cpu名称的方法: public string GetCpuInfo() { ManagementObjec ...

  5. Docker容器 获取宿主机CPU信息等或重启网卡命令操作介绍

    一.作用场景及知识点 1. 使用场景(SSH方式除外): A. 运行在Docker容器里面的程序,怎么采集宿主机的CPU.内存.磁盘等信息: B. 容器内更改宿主机的网卡信息,怎么操作宿主机执行命令: ...

  6. C#获取电脑型号、系统版本、内存大小、硬盘大小、CPU信息

    摘要 有时需要获取电脑的相关信息.这时可以通过调用windows api的方式,进行获取. 方法 可以通过在powershell中 通过下面的命令进行查询,然后可以通过c#调用获取需要的信息. gwm ...

  7. [No0000112]ComputerInfo,C#获取计算机信息(cpu使用率,内存占用率,硬盘,网络信息)

    github地址:https://github.com/charygao/SmsComputerMonitor 软件用于实时监控当前系统资源等情况,并调用接口,当资源被超额占用时,发送警报到个人手机: ...

  8. CPU测试--通过proc获取CPU信息

    adb shell cat /proc/stat | grep cpu > totalcpu0 此处第一行的数值表示的是CPU总的使用情况,所以我们只要用第一行的数字计算就可以了.下表解析第一行 ...

  9. 从Container内存监控限制到CPU使用率限制方案

    转自:http://blog.csdn.net/Androidlushangderen/article/details/50282593 前言 最近在运维我们部门的hadoop集群时,发现了很多Job ...

随机推荐

  1. java8-并行计算

    java8提供一个fork/join framework,fork/join框架是ExecutorService接口的一个实现,它可以帮助你充分利用你电脑中的多核处理器,它的设计理念是将一个任务分割成 ...

  2. linux sed 编辑

    只打印不修改内容 sed -n 's/sa/sa123/g' 1.txt  不加n是默认全部输出的意思 sed -n '1p' 1.txt  打印莫一行 sed a i c 表示追加 插入和替换 se ...

  3. DRF的视图与路由集Routers

    一 视图 Django REST framwork 提供的视图的主要作用: 控制序列化器的执行(检验.保存.转换数据) 控制数据库模型的操作 一 普通视图APIView 一 两个视图基类 1 APIV ...

  4. python内置函数len()

    len() len()函数用于返回对象(字符串.元组.列表和字典等)的长度或元素个数 len()函数的语法: len(s) 代码示例 print(len(range(10))) print(len([ ...

  5. BeautifulSoup模块的使用方法

    本篇文章主要讲bs4模块(BeautifulSoup),这个模块能做么呢?用一句话来概括的话:beautifulsoup4 从HTML或XML文件中提取数据的Python库,用它来解析爬取回来的xml ...

  6. IDEA-日志管理神器

    Grep Console-插件的好处就在于能使控制台输出日志时,可以直接修改插件中定义好的规则,也可以根据自己定义的规则,输出不同的颜色.这样就可以将错误信息标记成显眼的颜色,方便查看,提高bug寻找 ...

  7. 疯一样的向自己发问 - 剖析lsm 索引原理

    疯一样的向自己发问 - 剖析lsm 索引原理 lsm简析 lsm 更像是一种设计索引的思想.它把数据分为两个部分,一部分放在内存里,一部分是存放在磁盘上,内存里面的数据检索方式可以利用红黑树,跳表这种 ...

  8. 太坑了,我竟然从RocketMQ源码中扒出了7种导致消息重复消费的原因

    大家好,我是三友~~ 在众多关于MQ的面试八股文中有这么一道题,"如何保证MQ消息消费的幂等性". 为什么需要保证幂等性呢?是因为消息会重复消费. 为什么消息会重复消费? 明明已经 ...

  9. Java里if和else的用法

    前言 在上一篇文章中,壹哥给大家讲解了Java里的输入与输出语句,现在你知道怎么用了吗?接下来我们继续往下学习Java里的流程控制语句,今天先给大家讲一下if和else这一对好基友,这个知识点可以说是 ...

  10. Java面试——Spring

    一.Spring Bean 作用域 [1]singleton:该属性在 IOC容器仅创建一个 Bean实例(单例),IOC容器每次返回的是同一个 Bean实例.[2]prototype:该属性在 IO ...