当前位置: 首页 > news >正文

获取Fortran程序内存使用情况的方法

文章目录

  • 获取Fortran程序内存使用情况的方法
    • Linux系统下的方法
      • 1. 使用`getrusage`系统调用
      • 2. 读取/proc/self/statm文件
    • Windows系统下的方法
      • 1. 使用Windows API GetProcessMemoryInfo
    • 跨平台解决方案
    • 注意事项

获取Fortran程序内存使用情况的方法

在Fortran程序中获取当前进程的内存使用情况,可以通过以下几种方法实现,分别适用于Linux和Windows系统。

Linux系统下的方法

1. 使用getrusage系统调用

program memory_usageimplicit noneinteger, parameter :: RUSAGE_SELF = 0integer :: ierrinteger(kind=8) :: maxrssinterfacesubroutine getrusage(who, usage) bind(C, name="getrusage")use iso_c_bindinginteger(c_int), value :: whotype :: timevalinteger(c_long) :: tv_sec, tv_usecend typetype :: rusagetype(timeval) :: ru_utime, ru_stimeinteger(c_long) :: ru_maxrss, ru_ixrssinteger(c_long) :: ru_idrss, ru_isrssinteger(c_long) :: ru_minflt, ru_majfltinteger(c_long) :: ru_nswap, ru_inblockinteger(c_long) :: ru_oublock, ru_msgsndinteger(c_long) :: ru_msgrcv, ru_nsignalsinteger(c_long) :: ru_nvcsw, ru_nivcswend typetype(rusage) :: usageend subroutineend interfacetype :: rusageinteger(8) :: ru_utime_sec, ru_utime_usecinteger(8) :: ru_stime_sec, ru_stime_usecinteger(8) :: ru_maxrss, ru_ixrssinteger(8) :: ru_idrss, ru_isrssinteger(8) :: ru_minflt, ru_majfltinteger(8) :: ru_nswap, ru_inblockinteger(8) :: ru_oublock, ru_msgsndinteger(8) :: ru_msgrcv, ru_nsignalsinteger(8) :: ru_nvcsw, ru_nivcswend typetype(rusage) :: usagecall getrusage(RUSAGE_SELF, usage)print *, "Maximum resident set size (KB):", usage%ru_maxrss
end program

2. 读取/proc/self/statm文件

program read_proc_statmimplicit noneinteger :: unit, ierrinteger(kind=8) :: size, resident, share, text, lib, data, dtcharacter(len=256) :: lineopen(newunit=unit, file="/proc/self/statm", action="read", iostat=ierr)if (ierr /= 0) thenprint *, "Error opening /proc/self/statm"stopend ifread(unit, *, iostat=ierr) size, resident, share, text, lib, data, dtclose(unit)if (ierr /= 0) thenprint *, "Error reading /proc/self/statm"stopend if! 页面大小通常为4KBprint *, "Virtual memory size (pages):", sizeprint *, "Resident set size (pages):", residentprint *, "Shared pages:", shareprint *, "Text (code) pages:", textprint *, "Library pages:", libprint *, "Data/stack pages:", dataprint *, "Dirty pages:", dt! 转换为KBprint *, "Resident set size (KB):", resident * 4
end program

Windows系统下的方法

1. 使用Windows API GetProcessMemoryInfo

program windows_memory_usageuse, intrinsic :: iso_c_bindingimplicit none! 定义Windows API接口interfacefunction GetCurrentProcess() bind(C, name="GetCurrentProcess")use iso_c_bindingtype(c_ptr) :: GetCurrentProcessend functionfunction GetProcessMemoryInfo(hProcess, ppsmemCounters, cb) bind(C, name="GetProcessMemoryInfo")use iso_c_bindinginteger(c_int) :: GetProcessMemoryInfotype(c_ptr), value :: hProcesstype(c_ptr), value :: ppsmemCountersinteger(c_int), value :: cbend functionend interface! 定义PROCESS_MEMORY_COUNTERS结构体type, bind(C) :: PROCESS_MEMORY_COUNTERSinteger(c_int) :: cbinteger(c_int) :: PageFaultCountinteger(c_size_t) :: PeakWorkingSetSizeinteger(c_size_t) :: WorkingSetSizeinteger(c_size_t) :: QuotaPeakPagedPoolUsageinteger(c_size_t) :: QuotaPagedPoolUsageinteger(c_size_t) :: QuotaPeakNonPagedPoolUsageinteger(c_size_t) :: QuotaNonPagedPoolUsageinteger(c_size_t) :: PagefileUsageinteger(c_size_t) :: PeakPagefileUsageend typetype(PROCESS_MEMORY_COUNTERS) :: pmcinteger(c_int) :: successtype(c_ptr) :: hProcess! 初始化结构体大小pmc%cb = sizeof(pmc)! 获取当前进程句柄hProcess = GetCurrentProcess()! 获取内存信息success = GetProcessMemoryInfo(hProcess, c_loc(pmc), pmc%cb)if (success == 0) thenprint *, "Failed to get process memory info"elseprint *, "Working Set Size (KB):", pmc%WorkingSetSize / 1024print *, "Peak Working Set Size (KB):", pmc%PeakWorkingSetSize / 1024print *, "Pagefile Usage (KB):", pmc%PagefileUsage / 1024end if
end program

跨平台解决方案

为了编写跨平台的代码,可以使用预处理指令来区分不同操作系统:

program cross_platform_memoryuse, intrinsic :: iso_c_bindingimplicit none! 定义操作系统相关的预处理指令
#ifdef __linux__print *, "Linux memory usage:"call linux_memory_usage()
#elif _WIN32print *, "Windows memory usage:"call windows_memory_usage()
#elseprint *, "Unsupported operating system"
#endifcontains#ifdef __linux__subroutine linux_memory_usage()integer :: unit, ierrinteger(kind=8) :: residentcharacter(len=256) :: lineopen(newunit=unit, file="/proc/self/statm", action="read", iostat=ierr)if (ierr /= 0) thenprint *, "Error opening /proc/self/statm"returnend ifread(unit, *, iostat=ierr) line  ! 只需要第一个值close(unit)if (ierr /= 0) thenprint *, "Error reading /proc/self/statm"returnend if! 简单示例,实际应解析line获取resident值print *, "Resident set size (approximate, KB): (parse /proc/self/statm for actual value)"end subroutine
#endif#ifdef _WIN32subroutine windows_memory_usage()interfacefunction GetCurrentProcess() bind(C, name="GetCurrentProcess")use iso_c_bindingtype(c_ptr) :: GetCurrentProcessend functionfunction GetProcessMemoryInfo(hProcess, ppsmemCounters, cb) bind(C, name="GetProcessMemoryInfo")use iso_c_bindinginteger(c_int) :: GetProcessMemoryInfotype(c_ptr), value :: hProcesstype(c_ptr), value :: ppsmemCountersinteger(c_int), value :: cbend functionend interfacetype :: PROCESS_MEMORY_COUNTERSinteger(c_int) :: cbinteger(c_int) :: PageFaultCountinteger(c_size_t) :: PeakWorkingSetSizeinteger(c_size_t) :: WorkingSetSizeinteger(c_size_t) :: QuotaPeakPagedPoolUsageinteger(c_size_t) :: QuotaPagedPoolUsageinteger(c_size_t) :: QuotaPeakNonPagedPoolUsageinteger(c_size_t) :: QuotaNonPagedPoolUsageinteger(c_size_t) :: PagefileUsageinteger(c_size_t) :: PeakPagefileUsageend typetype(PROCESS_MEMORY_COUNTERS) :: pmcinteger(c_int) :: successtype(c_ptr) :: hProcesspmc%cb = sizeof(pmc)hProcess = GetCurrentProcess()success = GetProcessMemoryInfo(hProcess, loc(pmc), pmc%cb)if (success == 0) thenprint *, "Failed to get process memory info"elseprint *, "Working Set Size (KB):", pmc%WorkingSetSize / 1024end ifend subroutine
#endifend program

注意事项

  1. 在Linux上,/proc/self/statm提供的是以页面为单位的内存使用情况,通常页面大小为4KB。
  2. Windows API返回的值是以字节为单位的,需要除以1024转换为KB。
  3. 跨平台代码需要使用适当的编译器预处理指令来区分不同平台。
  4. 对于更复杂的需求,可能需要编写更多的C接口代码或使用第三方库。

以上方法可以帮助你在Fortran程序中获取当前进程的内存使用情况。

http://www.dtcms.com/a/274458.html

相关文章:

  • 多租户架构下的多线程处理实践指南
  • 上位机知识篇---Git符号链接
  • mysql 数据备份与数据恢复
  • BigFoot Decursive 2.7.28 2025.07.11
  • 伺服驱动控制CANopen协议
  • [WinForms] 如何为 .NET Framework 4.8 窗体程序添加自定义图标
  • 力扣面试150(29/100)
  • vue3 el-input 通过数组 获取显示
  • 上位机知识篇---网络通信端口
  • 【Nginx】实测Nginx增加第三方主动式健康检查模块
  • C++——构造函数的补充:初始化列表
  • C++11堆操作深度解析:std::is_heap与std::is_heap_until原理解析与实践
  • 操作系统内核链表操作接口
  • 基于机器视觉的半导体检测解决方案
  • 模拟心电图采样数据
  • 《PyQtGraph:Python绘图领域的“超级引擎”》
  • [ARC195E] Random Tree Distance
  • 完全和零一背包
  • 游戏开发日记
  • nginx 负载均衡配置(加解决重复登录问题)
  • Reading and Writing to a State Variable
  • stm32-modbus-rs485程序移植过程
  • gRPC服务注册和故障恢复
  • AI技术重塑工业制造:从智能应用到大型模型落地
  • AMTS AHTE | 具身智能成制造升级新引擎 灵途科技助力更强感知
  • 八股训练--RabbitMQ
  • LVS-NAT模式配置
  • 《Java 虚拟机内幕:从垃圾回收到类加载的深度解析》
  • 微积分核心考点全解析
  • pnpm 的 resolution-mode 配置 ( pnpm 的版本解析)