Swift で Mach から CPU 負荷、メモリ使用量を得るフレームワーク Mach-Swift

はじめに

iOS / macOS にて CPU 負荷、メモリ使用量を得るために Mach を使用する方法があります。
ただ、Mach の関数を直接使用するとポインタの扱いが手間なので、そのあたりを吸収した Swift フレームワークを作成しました。

github.com

使い方は以下です。

インストール

CocoaPods

Podfile を作成する

platform :ios, '10.0'    # iOS の場合
platform :osx, '10.12'   # macOS の場合
use_frameworks!

target 'YOUR-TARGET' do
    pod 'Mach-Swift', :git => 'https://github.com/daisuke-t-jp/Mach-Swift.git'
end

インストール

$ pod install

サンプルコード

ホスト(OS)

仮想メモリ情報

import Mach_Swift

// host_statistics(HOST_VM_INFO) 相当
let vm = Mach.Host.Statistics.vmInfo()
print("- freeSize: \(vm.freeSize)") // 空きサイズ (byte)
print("- activeSize: \(vm.activeSize)") // アクティブサイズ (byte)
print("- inactiveSize: \(vm.inactiveSize)") // 非アクティブサイズ (byte)
print("- wireSize: \(vm.wireSize)") // 固定サイズ (byte)
- freeSize: 130482176
- activeSize: 1765789696
- inactiveSize: 1649594368
- wireSize: 2495418368

CPU 負荷

import Mach_Swift

// host_statistics(HOST_CPU_LOAD_INFO) 相当
let cpuLoadInfo = Mach.Host.Statistics.cpuLoadInfo()
print("- userTick: \(cpuLoadInfo.userTick)")        // ユーザチック
print("- systemTick: \(cpuLoadInfo.systemTick)")    // システムチック
print("- idleTick: \(cpuLoadInfo.idleTick)")        // アイドルチック
print("- niceTick: \(cpuLoadInfo.niceTick)")        // ナイスチック
- userTick: 785470
- systemTick: 503253
- idleTick: 4632473
- niceTick: 0

基本情報

import Mach_Swift

// host_info(HOST_BASIC_INFO) 相当
let basicInfo = Mach.Host.Info.basicInfo()
print("- maxCPUs: \(basicInfo.maxCPUs)")    // CPU 総数
print("- availCPUs: \(basicInfo.availCPUs)")    // 利用可能 CPU 数
print("- memorySize: \(basicInfo.memorySize)")
print("- cpuType: \(basicInfo.cpuType)")
print("- cpuSubType: \(basicInfo.cpuSubType)")
print("- cpuThreadType: \(basicInfo.cpuThreadType)")
print("- physicalCPU: \(basicInfo.physicalCPU)")
print("- physicalCPUMax: \(basicInfo.physicalCPUMax)")
print("- logicalCPU: \(basicInfo.logicalCPU)")
print("- logicalCPUMax: \(basicInfo.logicalCPUMax)")
print("- maxMem: \(basicInfo.maxMem)")  // byte size
- maxCPUs: 4
- availCPUs: 4
- memorySize: 2147483648
- cpuType: 7
- cpuSubType: 8
- cpuThreadType: 1
- physicalCPU: 2
- physicalCPUMax: 2
- logicalCPU: 4
- logicalCPUMax: 4
- maxMem: 8589934592

プロセッサ(コア)

import Mach_Swift

// host_processor_info() 相当
let array = Mach.Host.Processor.cpuLoadInfoArray()
for i in 0..<array.count {
    let cpu = array[i]
    print("- Core No.\(i)")
    print("    - userTick: \(cpu.userTick)")
    print("    - systemTick: \(cpu.systemTick)")
    print("    - idleTick: \(cpu.idleTick)")
    print("    - niceTick: \(cpu.niceTick)")
    print("")
}
- Core No.0
    - userTick: 257206
    - systemTick: 186605
    - idleTick: 1036690
    - niceTick: 0

- Core No.1
    - userTick: 144763
    - systemTick: 87848
    - idleTick: 1247622
    - niceTick: 0

- Core No.2
    - userTick: 251769
    - systemTick: 155100
    - idleTick: 1073364
    - niceTick: 0

- Core No.3
    - userTick: 131732
    - systemTick: 73700
    - idleTick: 1274800
    - niceTick: 0

タスク(アプリ、プロセス)

基本情報

import Mach_Swift

// task_info() 相当
let basicInfo = Mach.Task.Info.basicInfo()
print("- virtualSize: \(basicInfo.virtualSize)")    // 仮想メモリサイズ (byte)
print("- residentSize: \(basicInfo.residentSize)")  // 実メモリサイズ(byte)
print("- residentSizeMax: \(basicInfo.residentSizeMax)")    // 実メモリ最大サイズ(byte)
print("- userTime: \(basicInfo.userTime)")      // ユーザ時間
print("- systemTime: \(basicInfo.systemTime)")      // システム時間
print("- policy: \(basicInfo.policy)")
print("- suspendCount: \(basicInfo.suspendCount)")
- virtualSize: 5425922048
- residentSize: 78155776
- residentSizeMax: 78155776
- userTime: 0.000426
- systemTime: 0.003031
- policy: 1
- suspendCount: 0

スレッド基本情報

import Mach_Swift

// task_threads() 相当
let array = Mach.Task.Thread.basicInfoArray()
for i in 0..<array.count {
    let thread = array[i]
    print("- Thread No.\(i)")
    print(String.init(format:"    - userTime: %.2f", thread.userTime))
    print(String.init(format:"    - systemTime: %.2f", thread.systemTime))
    print("    - cpuUsage: \(thread.cpuUsage)")
    print("    - policy: \(thread.policy)")
    print("    - runState: \(thread.runState)")
    print("    - flags: \(thread.flags)")
    print("    - suspendCount: \(thread.suspendCount)")
    print("    - sleepTime: \(thread.sleepTime)")
    print(String.init(format:"    - sleepTime: %.2f", thread.sleepTime))
    print("")
}
- Thread No.0
    - userTime: 0.24
    - systemTime: 0.93
    - cpuUsage: 626
    - policy: 1
    - runState: 1
    - flags: Flag(rawValue: 0)
    - suspendCount: 0
    - sleepTime: 0.0
    - sleepTime: 0.00

- Thread No.1
    - userTime: 0.01
    - systemTime: 0.01
    - cpuUsage: 23
    - policy: 1
    - runState: 3
    - flags: Flag(rawValue: 1)
    - suspendCount: 0
    - sleepTime: 0.0
    - sleepTime: 0.00

- Thread No.2
    - userTime: 0.00
    - systemTime: 0.00
    - cpuUsage: 6
    - policy: 1
    - runState: 3
    - flags: Flag(rawValue: 1)
    - suspendCount: 0
    - sleepTime: 0.0
    - sleepTime: 0.00

- Thread No.3
    - userTime: 0.00
    - systemTime: 0.00
    - cpuUsage: 0
    - policy: 1
    - runState: 3
    - flags: Flag(rawValue: 1)
    - suspendCount: 0
    - sleepTime: 0.0
    - sleepTime: 0.00

- Thread No.4
    - userTime: 0.00
    - systemTime: 0.00
    - cpuUsage: 4
    - policy: 1
    - runState: 3
    - flags: Flag(rawValue: 1)
    - suspendCount: 0
    - sleepTime: 0.0
    - sleepTime: 0.00

- Thread No.5
    - userTime: 0.00
    - systemTime: 0.01
    - cpuUsage: 12
    - policy: 1
    - runState: 3
    - flags: Flag(rawValue: 1)
    - suspendCount: 0
    - sleepTime: 0.0
    - sleepTime: 0.00

おわりに

Mach-Swift で取得できる情報を元に負荷をビュー表示するフレームワークもあります。

github.com