句柄问题分析

什么是句柄

句柄就是一个对象的标识符,只要获得对象的句柄,我们就可以对对象进行任意的操作,包括窗口,按钮,图标,输出设备,控件或者文件等;

句柄是一种特殊的智能指针,用一个唯一的整数值标识一个对象(即编号),并不指向实际的内核对象,而是内核对象的虚拟地址;

只有Windows中才有句柄,Windows中的句柄是指针的指针,因为windows中对象的经常会在内存中移动,所以地址值经常会变,所以就对外提供一个指针的指针即句柄给用户,句柄的地址是不会变的。

Linux中是没有文件句柄的,只有文件描述符,只是大家习惯把它说成句柄,Linux中, 每当进程打开一个文件时,系统就为其分配一个唯一对应的整型文件描述符,用来标识这个文件;

Windows之所以要设立句柄,根本上源于内存管理机制的问题—虚拟地址,简而言之数据的地址需要变动,变动以后就需要有人来记录管理变动,(就好像户籍管理一样),因此系统用句柄来记载数据地址的变更。

Windows系统中有许多内核对象(这里的对象不完全等价于"面向对象程序设计"一词中的"对象",虽然实质上还真差不多),比如打开的文件,创建的线程,程序的窗口,等等。这些重要的对象肯定不是4个字节或者8个字节足以完全描述的,他们拥有大量的属性。为了保存这样一个"对象"的状态,往往需要上百甚至上千字节的内存空间,那么怎么在程序间或程序内部的子过程(函数)之间传递这些数据呢?拖着这成百上千的字节拷贝来拷贝去吗?显然会浪费效率。那么怎么办?当然传递这些对象的首地址是一个办法,但这至少有两个缺点:

暴露了内核对象本身,使得程序(而不是操作系统内核)也可以任意地修改对象地内部状态(首地址都知道了,还有什么不能改的?),这显然是操作系统内核所不允许的;

操作系统有定期整理内存的责任,内存管理器经常在内存中来回移动对象,依此来满足各种应用程序的内存需要,对象被移动意味着它的地址变化了,如果地址总是如此变化,我们该到哪里去找该对象呢? 

所以,Windows操作系统就采用进一步的间接:在进程的地址空间中设一张表,表里头专门保存一些编号和由这个编号对应一个地址,而由那个地址去引用实际的对象,这个编号跟那个地址在数值上没有任何规律性的联系,纯粹是个映射而已。这个编号就叫做"句柄"。


关于Windows句柄

Windows对象和句柄类型

Windows对象分为内核对象、GDI对象和User对象:

内核对象是不属于进程的,是属于windows内核的。进程只有一个内核对象句柄表,用来存放所有的内核对象句柄。所以,多个进程可以同时使用一个内核对象 ,只要有句柄即可。

对于GDI对象和User对象,他们是一个进程内部拥有的东西,不会被多个进程共有。GDI对象与绘图相关,而User对象与交互相关。

内核对象如文件、进程、线程等;GDI对象如字体、画笔、位图等;User对象如图标、菜单、窗体等,不同对象对应着不同类型的句柄,如文件句柄、窗体句柄等;

查看句柄

通过任务管理器

查看句柄

通过Process Explorer工具,点击进程右键、属性、性能选项卡查看:

查看句柄

Handles为内核对像的句柄,包括文件句柄,GDI 和User分别是GDI句柄和User句柄。

修改句柄

文件句柄数默认为512,GDI句柄默认为10000,User句柄默认为10000;

GDI和User句柄可通过注册表修改,修改“GDIProcessHandleQuota”与“USERProcessHandleQuota”注册表项:

修改句柄


关于Linux句柄

Linux中类似Windowns句柄的是fd,在Linux系统设计里面遵循一切都是文件的原则,即磁盘文件、目录、网络套接字、磁盘、管道等,所有这些都是文件,在我们进行打开的时候会返回一个fd,即是文件句柄,Linux不存在具体的句柄类型。

查看句柄

ulimit -n:查看当前用户单个进程能够打开的最大文件句柄数量(包括Socket链接),默认是1024

lsof -n |awk '{print $2}'|sort|uniq -c |sort -nr|more:查看所有进程的句柄数量(降序排序),第一列是句柄数,第二列是PID;

lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr|more |grep <pid>:查看某个进程的句柄数;

修改句柄

方法1:ulimit -HSn 4096:修改句柄数为4096,仅对当前进程有效,关闭或重启失效;

方法2:修改linux系统参数。vi /etc/security/limits.conf 添加

*  soft  nofile  2048

*  hard  nofile  32768 

就可以将文件句柄限制统一改成软2048,硬32768,硬限制是实际的限制,而软限制,是warnning限制,只会做出warning ;

修改以后保存,注销当前用户,重新登录,执行ulimit -a 查看当前状态是否生效。


句柄问题

1. 句柄泄露:句柄只增不减,一般是由于各类资源未释放,如Socket、文件等;

2. too many files open:这里的file不只是指文件,包括Socket连接等,当句柄数超过了限制,进程将无法获取新的句柄,而从导致不能打开新的文件或者网络套接字,对于线上Server即会出现服务被拒绝的情况;

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容