为啥文件句柄如此昂贵的资源?

Posted

技术标签:

【中文标题】为啥文件句柄如此昂贵的资源?【英文标题】:Why are file handles such an expensive resource?为什么文件句柄如此昂贵的资源? 【发布时间】:2010-12-23 11:14:26 【问题描述】:

在关于垃圾收集是否是一件好事的圣战中,人们经常指出它不能处理诸如释放文件句柄之类的事情。将此逻辑放入终结器中被认为是一件坏事,因为资源随后会被非确定性地释放。然而,对于操作系统来说,一个简单的解决方案似乎是确保大量文件句柄可用,以便它们是一种廉价而丰富的资源,并且您可以在任何给定时间浪费一些。为什么在实践中不这样做?

【问题讨论】:

【参考方案1】:

实际上,这是无法做到的,因为操作系统必须分配更多的内存开销来跟踪不同进程正在使用哪些句柄。在如下所示的示例 C 代码中,我将演示一个存储在循环队列中的简单 OS 进程结构,例如...

结构过程记录 整数进程ID; CPURegs cpuRegs; 任务指针**孩子; int *baseMemAddress; int sizeOfStack; int sizeOfHeap; int *baseHeapAddress; int 粒度; 时间; 枚举状态正在运行,可运行,僵尸...; /* ...这里还有几个字段... */ 长*文件句柄; 长文件句柄计数; 程序;

想象一下,fileHandles 是一个指向整数数组的指针,其中每个整数都包含在操作系统表中文件存储在磁盘上的位置(可能是编码格式)的偏移量。

现在想象一下,有多少内存会吃掉并减慢整个内核的速度,可能会带来不稳定,因为系统的“多任务”概念会因为必须跟踪文件句柄的数量而崩溃正在使用中,并提供一种机制来动态增加/减少指向整数的指针,如果操作系统根据用户程序的需求提供文件句柄,这可能会影响用户程序的速度。

我希望这可以帮助您理解为什么它没有实现也不实用。

希望这是有道理的, 最好的祝福, 汤姆。

【讨论】:

您能否评论一下为什么这被否决了?谢谢。 :| @RCIX:谢谢 - 发帖速度太快了,我没有发表评论就被否决了…… @hobbs:真的吗?许多操作系统实际上确实为这种事情提供了单独的预分配内存池,以消除动态分配的开销。 @hobbs:他的数组在我看来并不是静态的。 long* 和 long 计数看起来是动态的。【参考方案2】:

关闭文件也会刷新对磁盘的写入 - 无论如何,从您的应用程序的角度来看。关闭文件后,应用程序可能会崩溃,只要系统本身不崩溃,更改就不会丢失。因此,让 GC 随意关闭文件并不是一个好主意。即使现在在技术上可能是可行的。

而且,说实话,旧习惯很难改掉。文件句柄过去很昂贵,并且可能由于历史原因仍然被认为是昂贵的。

【讨论】:

【参考方案3】:

这不仅仅是文件句柄的数量,有时当它们在某些模式下使用时,它们会阻止其他调用者访问同一个文件。

【讨论】:

没错。问题通常不在于句柄的总数是有限的,而是可以对特定文件打开的独占句柄的数量非常有限,通常是一个 i>. @supercat 这听起来像是 Windows 特定的限制。 @binki:可以对任何特定文件打开的独占句柄的数量在任何未损坏的实现中都将被限制为一个。【参考方案4】:

我敢肯定会有更全面的答案,但根据我有限的经验和对 Windows 底层操作的理解,文件句柄(用于向操作系统表示它们的结构)是内核对象,因此它们需要某些类型的内存可用 - 更不用说内核部分的处理以保持与需要访问相同资源(即文件)的多个进程的一致性和连贯性

【讨论】:

如果您指的是内核空间内存,那么 64 位内核在现在和可预见的未来可能需要尽可能多的内存。【参考方案5】:

我认为它们不一定很昂贵 - 如果您的应用程序只打开了一些不必要的应用程序,它不会杀死系统。就像你在 C++ 中只泄漏了几个字符串一样,没有人会注意到,除非它们看起来很仔细。问题出在哪里:

如果泄漏成百上千 如果打开文件会阻止对该文件进行其他操作(其他应用程序可能无法打开或删除该文件) 这是马虎的标志 - 如果您的程序无法跟踪它拥有的、正在使用或已停止使用的内容,那么该程序还会出现什么其他问题?有时,当一些小变化或用户做的事情与以前略有不同时,小泄漏会变成大泄漏。

【讨论】:

当然,除非您的缓冲区没有正确写入,因为您的泄漏文件句柄没有正确关闭。在那种——非常常见的——情况下,单个泄露的句柄可能是调试的噩梦。【参考方案6】:

在 Linux 范例中,套接字是文件描述符。尽快释放 TCP 端口有一定的优势。

【讨论】:

以上是关于为啥文件句柄如此昂贵的资源?的主要内容,如果未能解决你的问题,请参考以下文章

Linux下的“句柄”(文件句柄,窗口句柄)

iNotify 收到事件后如何关闭文件句柄

cURL下载Zip文件 - “参数不是有效的文件句柄资源”

模块句柄(实例句柄)和句柄的区别

Linux中如何解除最大进程数和最大文件句柄打开数限制?

解除Linux最大进程数和最大文件句柄打开数限制