当一个进程被初始化时,系统要为它分配一个句柄表。该句柄表只用于内核对象 ,不用于用户对象或G D I对象。它只是个数据结构的数组。每个结构都包含一个指向内核对象的指针、一个访问屏蔽和一些标志
当进程初次被初始化时,它的句柄表是空的。然后,当进程中的线程调用创建内核对象的函数时,比如C r e a t e F i l e M a p p i n g,内核就为该对象分配一个内存块,并对它初始化。
用于创建内核对象的所有函数均返回与进程相关的句柄,这些句柄可以被在相同进程中运行的任何或所有线程成功地加以使用。该句柄值实际上是放入进程的句柄表中的索引,它用于标识内核对象的信息存放的位置。因此当调试一个应用程序并且观察内核对象句柄的实际值时,会看到一些较小的值,如1,2等。
每当调用一个将内核对象句柄接受为参数的函数时,就要传递由一个Create*&函数返回的值。从内部来说,该函数要查看进程的句柄表,以获取要生成的内核对象的地址,然后按定义得很好的方式来生成该对象的数据结构。如果传递了一个无效索引(句柄),该函数便返回失败,而GetLastError则返回6(ERROR_INVALID_HANDLE)。由于句柄值实际上是放入进程句柄表的索引,因此这些句柄是与进程相关的,并且不能由其他进程成功地使用。
无论怎样创建内核对象,都要向系统指明将通过调用CloseHandle来结束对该对象的操作。
简单来说就是,系统有一个如同jvm一样的垃圾回收机制,对内核对象的引用计数,引用为0的会被回收,只是需要你手动清除引用。