studio recursos programacion para móviles libros gratis edición desarrollo desarrollar curso con aprende aplicaciones java effective-java

java - recursos - ¿Qué es un recurso no de memoria?



programacion android pdf 2018 (4)

¿Es una conexión de base de datos un recurso no de memoria?

Sí, ese es uno de los ejemplos más comunes. Otros son identificadores de archivos, objetos GUI nativos (por ejemplo, ventanas Swing o AWT) y sockets.

¿El Objeto para mantener la conexión de la base de datos no ocupa algo de memoria?

Sí, pero el punto es que la parte que no tiene memoria del recurso también debe liberarse y, por lo general, es mucho más escasa que la cantidad de memoria comparativamente pequeña que utiliza el objeto. Normalmente, estos objetos tienen un método finalize() que libera el recurso que no es de memoria, pero el problema es que estos finalizadores solo se ejecutarán cuando los objetos se recolecten como basura.

Dado que los objetos son pequeños, puede haber suficiente memoria de almacenamiento disponible para que el recolector de basura se ejecute rara vez. Y entre las ejecuciones del recolector de basura, los recursos que no son de memoria no se liberan y usted puede quedarse sin ellos.

Esto puede incluso causar problemas con un solo objeto: por ejemplo, si desea mover un archivo entre sistemas de archivos abriéndolo, abriendo el archivo de destino, copiando los datos y luego eliminando el archivo original, la eliminación fallará si el archivo es aún está abierto, y es casi seguro que lo sea si solo establece la referencia a la secuencia de entrada en nulo y no llama a close() explícitamente, porque es muy poco probable que el recolector de basura se haya ejecutado exactamente en el punto correcto entre el el objeto se convierte en elegible para la recolección de basura y la llamada a delete()

Estoy leyendo " Java efectiva ".

En la discusión sobre finalizar, él dice

Los destructores de C ++ también se utilizan para reclamar otros recursos no de memoria. En Java, el bloque try finally se usa generalmente para este propósito.

¿Qué son los recursos que no son de memoria?

¿Es una conexión de base de datos un recurso no de memoria? ¿El objeto para mantener la conexión de base de datos no ocupa algo de memoria?


Conexiones de base de datos, conexiones de red, identificadores de archivos, exclusión mutua, etc. Algo que debe liberarse (no solo recoger basura) cuando termine.

Sí, estos objetos normalmente ocupan algo de memoria, pero el punto crítico es que también tienen acceso (posiblemente exclusivo) a algún recurso además de la memoria.


En mi opinión, la pregunta se responde mejor al revés: "¿por qué no necesito liberar memoria manualmente?".

Esto plantea la pregunta, ''¿por qué necesito liberar recursos?''

Fundamentalmente, su programa en ejecución utiliza muchas formas de recursos para ejecutar y hacer trabajo (ciclos de CPU, ubicaciones de memoria, acceso a disco, etc.). Casi todos estos sufren de "escasez", es decir, hay un conjunto fijo de cualquier recurso disponible, si se asignan todos los recursos, el sistema operativo no puede satisfacer las solicitudes y, en general, su programa no puede continuar y muere sin gracia. posiblemente haciendo todo el sistema inestable. Lo único que viene a la mente que no es escaso son los ciclos de CPU, puede emitir tantos como desee, solo está limitado por la velocidad a la que puede emitirlos, no se consumen de la misma manera. Sentir que los identificadores de memoria o archivo son.

Por lo tanto, cualquier recurso que use (memoria, manejadores de archivos, conexiones de base de datos, sockets de red, etc.) proviene de una cantidad fija de dicho recurso (evitando la palabra ''grupo'') y como su programa (y, otros, los que tienen en cuenta) programas, sin mencionar el sistema operativo en sí) asigna estos recursos, la cantidad disponible disminuye.

Si un programa solicita y se le asignan recursos y nunca los libera para usarlos en otro lugar, eventualmente (a menudo pronto) el sistema se quedará sin dichos recursos. En ese momento, el sistema se detiene o, a veces, el programa ofensivo puede eliminarse de forma abrupta.

Antes de los 90, la gestión de recursos (al menos en el desarrollo general) era un problema que todos los programadores tenían que tratar explícitamente. La administración de la asignación de recursos no es demasiado difícil, principalmente porque la asignación ya está abstraída (por ejemplo, los manejadores de archivos o los sockets de red) y uno puede obtener el recurso, usarlo y liberarlo explícitamente cuando ya no sea necesario.

Sin embargo, administrar la memoria es muy difícil, particularmente porque la asignación de memoria no se puede calcular (en situaciones no triviales) en el momento del diseño, mientras que, digamos, las conexiones de base de datos pueden manejarse de esta manera. (No hay forma de saber cuánta memoria utilizará, es muy difícil / imposible saber cuándo una asignación de memoria ya no está en uso). Además, las asignaciones de memoria tienden a ralentizarse durante un tiempo, donde la mayoría de las otras asignaciones de recursos se limitan a un ámbito limitado, a menudo dentro de un único bloque de intentos, o un método, en la mayoría de los casos una clase. Por lo tanto, los proveedores desarrollaron métodos para abstraer la asignación de memoria y colocarla en un solo sistema de administración, manejado por el entorno de ejecución, no por el programa.

Esta es la diferencia entre los entornos administrados (por ejemplo, Java, .NET) y los no administrados (por ejemplo, C, C ++ ejecutado directamente a través del sistema operativo). En C / C ++, la asignación de memoria se realiza explícitamente (con malloc () / nueva y reasignación asociada), lo que conduce a todo tipo de problemas: ¿cuánto necesito? ¿Cómo calculo cuando necesito más / menos? ¿Cómo libero la memoria? ¿Cómo me aseguro de no usar la memoria que ya se ha liberado? ¿Cómo detecto y administro situaciones en las que falla una solicitud de asignación de memoria? ¿Cómo evito escribir sobre la memoria (tal vez ni siquiera mi propia memoria)? Todo esto es extremadamente difícil y conduce a fugas de memoria, volcados de memoria y todo tipo de errores semi-aleatorios, no reproducibles.

Entonces, Java implementa la gestión automática de la memoria. El programador simplemente asigna un nuevo objeto y no está interesado, ni debería estar en términos de qué o dónde se asigna la memoria (esta es la razón por la que no hay muchos punteros en los entornos administrados):

object thing = new Object();

y eso es todo lo que hay que hacer. La JVM mantendrá un registro de qué memoria está disponible, cuándo necesita ser asignada, cuándo puede liberarse (ya que ya no está en uso), brindando formas de lidiar con las situaciones fuera de la memoria con la mayor gracia posible (y limitando cualquier problema al ejecutando subprocesos / JVM y no derribando todo el sistema operativo).

La administración automática de la memoria es el estándar con la mayoría de la programación ahora, ya que la administración de la memoria es, con mucho, el recurso más difícil de administrar (sobre todo porque otros ya están, hasta cierto punto, agrupados de conexiones de bases de datos, abstracciones de socket, etc.).

Entonces, para responder a la pregunta, sí, necesita administrar todos los recursos, pero en Java no necesita (y no puede) administrar la memoria de manera explícita (aunque vale la pena considerarla en algunas situaciones, por ejemplo, diseñar un caché). Esto deja todos los demás recursos que necesita para administrar explícitamente (y estos son los recursos que no son de memoria, es decir, todo excepto la creación / destrucción de objetos).

Todos estos otros recursos están envueltos en un recurso de memoria, claramente, pero ese no es el problema aquí. Por ejemplo, hay un número finito de conexiones de base de datos que puede abrir, un número finito de identificadores de archivos que puede crear. Necesitas gestionar la asignación de estos. El uso del bloque finally le permite asegurarse de que los recursos se desasignen, incluso cuando se produce una excepción.

p.ej

public void server() { try { ServerSocket serverSocket = new ServerSocket(25); } catch (Exception exception) { // Something went wrong. } finally { // Clear up and deallocate the unmanaged resource serverSocket here. // The close method will internally ensure that the network socket is actually flushed, closed and network resources released. serverSocket.close(); // The memory used by serverSocket will be automatically released by the JVM runtime at this point, as the serverSocket has gone out-of-scope- it is never used again, so can safely be deallocated. } }