6

En las guerras santas sobre si la recolección de basura es algo bueno, la gente a menudo señala que no maneja cosas como liberar manejadores de archivos. Poner esta lógica en un finalizador se considera algo malo porque el recurso se libera de manera no determinista. Sin embargo, parece que una solución fácil sería que el sistema operativo simplemente se asegurara de que haya montones y montones de identificadores de archivos disponibles para que sean un recurso barato y abundante y pueda permitirse desperdiciar algunos en un momento dado. ¿Por qué no se hace esto en la práctica?¿Por qué los manejadores de archivos son un recurso tan costoso?

Respuesta

2

El cierre de un archivo también vacía las escrituras en el disco, bueno, desde el punto de vista de su aplicación de todos modos. Después de cerrar un archivo, la aplicación puede fallar, siempre que el sistema no falle, los cambios no se perderán. Por lo tanto, no es una buena idea dejar que el GC cierre los archivos cuando lo desee. Incluso si puede ser técnicamente posible hoy en día.

Además, a decir verdad, los viejos hábitos se vuelven difíciles. Los identificadores de archivos solían ser caros y probablemente todavía se consideren como tales por razones históricas.

2

No es solo la cantidad de manejadores de archivos, es que a veces, cuando se utilizan en algunos modos, pueden evitar que otras personas que llaman puedan acceder al mismo archivo.

+1

Exactamente. El problema a menudo no es que la cantidad total de identificadores sea limitada, sino que el número de identificadores exclusivos que se pueden abrir * para un archivo en particular * es muy limitado, generalmente a * UNO *. – supercat

+0

@supercat Eso suena como una limitación específica de Windows. – binki

+1

@binki: El número de identificadores * exclusive * que pueden abrirse para cualquier archivo en particular estará limitado a uno en cualquier implementación no interrumpida. – supercat

2

Estoy seguro de que obtendrán respuestas más completas, pero en base a mi limitada experiencia y comprensión del funcionamiento subyacente de Windows, los identificadores de archivos (las estructuras utilizadas para representarlos en el SO) son objetos kernel y como tales requieren un cierto tipo de memoria para estar disponible, sin mencionar el procesamiento en la parte kernel para mantener la consistencia y coherencia con múltiples procesos que requieren acceso a los mismos recursos (es decir, archivos)

+0

Si se refiere a la memoria de kernel-space, un kernel de 64 bits tiene todo lo que pueda necesitar ahora y en el futuro previsible. –

1

No creo que sean necesariamente caros - si su aplicación solo contiene algunas poco responsables, no matará al sistema. Al igual que si se filtran solo unas pocas cuerdas en C++, nadie lo notará, a menos que estén mirando con cuidado. Donde se convierte en un problema es:

  • si hay fugas de cientos o miles
  • si tener la apertura de archivo impide que otras operaciones que se produzcan en ese archivo (otras aplicaciones podrían no ser capaz de abrir o eliminar el archivo)
  • es una señal de descuido: si su programa no puede realizar un seguimiento de lo que posee y está usando o ha dejado de usar, ¿qué otros problemas tendrá el programa? A veces, una pequeña fuga se convierte en una gran fuga cuando algo pequeño cambia o un usuario hace algo un poco diferente que antes.
+0

A menos que, por supuesto, sus almacenamientos intermedios no se escriban correctamente porque su identificador de archivo filtrado no se cerró correctamente. En ese caso, muy común, un solo identificador filtrado puede ser una pesadilla de depuración. –

5

En la práctica, no se puede hacer porque el sistema operativo tendría que asignar mucha más sobrecarga de memoria para hacer un seguimiento de qué controladores están en uso por diferentes procesos. En un ejemplo de código C como se muestra a continuación voy a demostrar una estructura de proceso de OS sencilla almacenado en una cola circular para un ejemplo ...

 
struct ProcessRecord{ 
    int ProcessId; 
    CPURegs cpuRegs; 
    TaskPointer **children; 
    int *baseMemAddress; 
    int sizeOfStack; 
    int sizeOfHeap; 
    int *baseHeapAddress; 
    int granularity; 
    int time; 
    enum State{ Running, Runnable, Zombie ... }; 
    /* ...few more fields here... */ 
    long *fileHandles; 
    long fileHandlesCount; 
}proc; 

Imagine que filehandles es un puntero a una matriz de números enteros que cada entero contiene el ubicación (tal vez en formato codificado) para el desplazamiento en la tabla del sistema operativo donde se almacenan los archivos en el disco.

Ahora imagina cuánta memoria se comería y podría ralentizar a todo el kernel, tal vez generar inestabilidad ya que el concepto de "multitarea" del sistema se caería como resultado de tener que realizar un seguimiento de cuánto manejadores de archivos están en uso y para proporcionar un mecanismo para aumentar/disminuir dinámicamente el puntero a enteros que podrían tener un efecto de arrastre en la ralentización del programa de usuario si el sistema operativo distribuye manejadores de archivos según la demanda del programa de usuario.

Espero que esto lo ayude a comprender por qué no está implementado ni es práctico.

Espero que esto tenga sentido, Saludos cordiales, Tom.

+0

¿Puede dejar un comentario sobre por qué esto fue downvoted? Gracias. : | – t0mm13b

+0

No hay idea de por qué esto fue votado negativamente ... +1 – RCIX

+0

@RCIX: Gracias - es increíble a la velocidad de publicación. Recibí downvoted sin dejar ningún comentario ... – t0mm13b

0

En Linux, los sockets de paradigma son descriptores de archivos. Existen ventajas definitivas para liberar puertos TCP tan pronto como sea posible.

Cuestiones relacionadas