当我们写代码,程序时,经常会创建内核对象。系统会创建和处理几种类型的内核对象,比如访问令牌对象,事件对象,文件对象,互斥量对象,进程对象,线程对象等。每个内核对象都只是一个内存块,它由操作系统内核访问。这个内存块是一个数据结构其成员维护着与对象相关的信息。对于使用计数是所有对象都有的,因为我们需要它来控制进程的生死。
    我们的进程调用函数来创建一个内核对象,当进程终止运行,该内核对象不一定会销毁。假如有两个进程共用一个内核对象,其中一个进程结束了,但另外的进程还在运行,那么在这个没结束的线程结束之前,它就不会销毁。因为有人需要,我就得提供。因此,一个内核对象的生命周期可能长于创建它的那个进程。
    为了确保没有多余的内核对象浪费,操作系统使用一个小技巧-引用计数。使用计数是所有内核对象类型都有的一个数据成员。为什么呢?当我们的进程创建一个内核对象的时候,其引用计数设为1.当另外的进程获得对现有内核对象的访问后,引用计数就会递增。进程结束后,操作系统内核将自动递减此进程打开或访问的所有内核对象的引用计数。
指针计数,记录了内核本身引用该对象的次数;句柄计数,它记录了有多少个句柄引用此对象,这些句柄可能出现在不同的进程中。
    对象是通过引用计数来管理其生命周期的,一旦引用计数为零,则对象的生命周期结束,他所占的内存也就被回收了(如果你不想造成内存浪费的话)。对象的引用计数来源于两个方面:第一个就是内核的指针引用,记录了内核本身引用该对象的次数,一旦内核中新增了一个对象的引用也就是说有进程访问内核对象的话,则对象的引用计数增一,具体的实现就是windows内核代码了,我也知之不深,就不详述了;第二个来源就是,一个进程打开一个对象并获得一个句柄,他以后通过此句柄来引用此对象,当句柄不再使用也就是我们经常调用函数closehandle()时,其句柄计数减一。句柄计数,它记录了有多少个句柄引用此对象,这些句柄可能出现在不同的进程中。
    无论以什么当时创建内核对象,我们都要调用closehandle向系统表明我们已经结束使用对象。
    
BOOL CloseHandle(HANDLE hobject)

在操作系统内核内部代码中,该函数首先检查主调进程的句柄表,验证“传给函数的句柄值”标识的是“进程确实有权访问的一个对象”。如果句柄是有效的,系统就将获得内核对象的数据结构的地址。并将结构中的引用计数“递减。引用计数为零,则对象的生命周期结束。
    就在closehandle函数返回之前,它会清除进程句柄表中对应的记录项-这个句柄现在对我们的进程来说是无效的,不要再试图用它。无论内核对象当前是否销毁,这个清除过程都会发生!一旦调用closehandle,我们的进程就不能再访问该进程之前访问过的内核对象,但是,如果对象的引用计数还没有递减至0,它就不会被销毁,这说明还有别的进程在访问它。

    我们来瞅瞅我们此前的用到的线程数,句柄数:找到资源管理器,选择查看->选择列,然后在选择进程页列对话框中,指定在进程选项卡中显示句柄数列。