C++如何获取系统当前的全局句柄引用总数统计 _ 资源分析接口【实战】

小婷酱_9840

小婷酱_9840

2026-04-29

493人浏览

原创

windows无api直接返回全局句柄引用总数;getprocesshandlecount仅统计本进程句柄槽位数,不反映真实引用压力;ntquerysysteminformation可枚举全系统句柄条目总数,但需调试权限且非去重引用计数。

c++如何获取系统当前的全局句柄引用总数统计 _ 资源分析接口【实战】

Windows 系统没有公开、稳定、跨版本的 API 直接返回“全局句柄引用总数”——这个数值在内核中是分散维护的(每个进程独立句柄表 + 全局对象引用计数),GetProcessHandleCount 只能查本进程,NtQuerySystemInformation 的 SystemHandleInformation 类别虽可枚举全系统句柄,但开销大、需管理员权限、且返回的是句柄条目数(含重复引用),不是严格意义上的“引用总数”。

为什么 GetProcessHandleCount 不行?它只返回当前进程的句柄数

这个函数本质是读取当前进程 EPROCESS 结构里的 HandleCount 字段,完全不涉及其他进程或内核对象的引用关系。它甚至不区分句柄是否有效、是否被多处重复 DuplicateHandle —— 它只是个句柄表槽位计数器。

  • 调用后返回值通常远小于你用 Process Explorer 看到的“Handles”列(后者是实时枚举结果)
  • 对调试资源泄漏无直接帮助:一个泄漏的 HANDLE 可能被 DuplicateHandle 复制 5 次,GetProcessHandleCount 仍只算 1 个
  • 无法反映内核对象真实引用压力,比如一个 Section 对象被 20 个进程各持有一个句柄,它的总引用数是 20,但没有任何单进程 API 能聚合出这个 20

用 NtQuerySystemInformation 枚举所有句柄并统计(需 SeDebugPrivilege)

这是最接近“全局句柄引用总数”的实操路径,但要注意:它返回的是“句柄实例数”,即所有进程打开的所有句柄条目之和(含重复),不是去重后的对象数,更不是引用计数总和。但它能暴露资源使用全景。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 必须启用调试权限:AdjustTokenPrivileges 启用 SE_DEBUG_NAME,否则调用直接失败(STATUS_PRIVILEGE_NOT_HELD)
  • 信息类必须用 SystemHandleInformation(值为 16),Windows 10/11 上推荐改用 SystemExtendedHandleInformation(值为 64),它包含所有者进程 ID 和对象类型名,避免手动解析 ObjectTypeIndex
  • 缓冲区需循环调用:第一次传 NULL 获取所需大小,再分配内存重试;失败时检查 STATUS_INFO_LENGTH_MISMATCH
  • 枚举结果里每个 SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX 的 HandleValue 是句柄值,UniqueProcessId 是所属进程,HandleCount 字段在此结构中**不存在**——别和进程句柄计数混淆
// 简化示意:获取总句柄条目数(非引用总数)
ULONG size = 0;
NTSTATUS status = NtQuerySystemInformation(SystemExtendedHandleInformation, nullptr, 0, &size);
if (status == STATUS_INFO_LENGTH_MISMATCH) {
    auto buf = std::make_unique<uchar>(size);
    status = NtQuerySystemInformation(SystemExtendedHandleInformation, buf.get(), size, &size);
    if (NT_SUCCESS(status)) {
        auto info = reinterpret_cast<psystem_handle_information_ex>(buf.get());
        DWORD total_handles = info->NumberOfHandles; // 这就是所有进程句柄条目的总和
    }
}</psystem_handle_information_ex></uchar>

真正有意义的“引用总数”只能按对象类型分组统计

如果你关心的是“有多少个线程对象正被引用”或“Event 对象总引用数是否异常增长”,就必须在 NtQuerySystemInformation 结果基础上,按 ObjectTypeIndex 或 ObjectTypeName(SystemExtendedHandleInformation 提供)做聚合。Windows 内核里每个对象头都有 PointerCount 和 HandleCount,但这两个值**不对外暴露**——你只能通过枚举所有句柄,然后按对象地址(Object 字段)去重计数,才接近真实对象实例数;而“引用总数”仍需额外跟踪每个对象的生命周期,实际不可行。

  • 同一个内核对象地址(Object 字段)出现在多个句柄条目中,说明它被多个进程/线程引用
  • 用 std::map<uintptr_t int></uintptr_t> 统计每个 Object 地址出现次数,得到近似“对象级引用频次”,但这仍是启发式估算
  • 32 位系统上 Object 是指针,64 位需用 ULONGLONG;不同 Windows 版本该字段偏移可能变化,SystemExtendedHandleInformation 更可靠
  • 此方法无法区分“引用”和“句柄”:一个进程对同一对象重复 DuplicateHandle 会产生多个句柄条目,指向同一 Object 地址,它们共同构成对该对象的一组引用

想靠一个数字判断系统资源瓶颈,不如盯紧具体进程的句柄泄漏(用 GetProcessHandleCount 配合定时采样)、或用 ETW 事件 Microsoft-Windows-Kernel-Process/ProcessConfiguration 捕获句柄创建/关闭;全局句柄总数本身意义有限,因为 Windows 默认限制是 16,777,216 个句柄,而实际瓶颈往往出现在 GDI/User 对象(GetGuiResources)或分页池耗尽上。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2248

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

1019

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

427

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

327

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

406

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

580

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1409

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1217

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1325

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习