La Red de Conocimientos Pedagógicos - Currículum vitae - ¿El desbordamiento de memoria en Java y el desbordamiento de memoria en C son el mismo concepto?

¿El desbordamiento de memoria en Java y el desbordamiento de memoria en C son el mismo concepto?

Desbordamiento de memoria y pérdidas de memoria en Java

Desbordamiento de memoria:

Para toda la aplicación, no se asigna espacio adicional al nuevo objeto de memoria JVM. . Entonces se produce un desbordamiento de la memoria.

Pérdida de memoria:

Durante todo el ciclo de vida de la aplicación, siempre existe un objeto y el espacio de memoria ocupado por el objeto se hace cada vez más grande, lo que eventualmente conduce a una memoria JVM. fuga.

p>

Por ejemplo: para aplicaciones de almacenamiento en caché, si no se establece un límite superior, la capacidad de la caché puede seguir creciendo.

Referencia de colección estática: si la colección almacena innumerables objetos, la capacidad puede crecer sin límite con el tiempo, lo que eventualmente provocará pérdidas de memoria en JVM.

Una pérdida de memoria se produce cuando un objeto en la aplicación sobrevive durante mucho tiempo y ocupa más espacio, lo que eventualmente conduce a una pérdida de memoria.

Es el crecimiento de la capacidad a largo plazo después de la asignación del objeto.

El desbordamiento de memoria se refiere a un espacio asignado insuficiente para todos los objetos en toda la aplicación, lo que provocará un desbordamiento de la memoria.

Pérdida de memoria

Una pérdida de memoria se refiere a una situación en la que un programa no puede liberar memoria que ya no se utiliza debido a negligencia o error. Las pérdidas de memoria no significan la desaparición física de la memoria, sino que luego de que la aplicación asigna un determinado segmento de memoria, debido a errores de diseño, pierde el control del segmento de memoria, provocando así un desperdicio de memoria. Las pérdidas de memoria tienen síntomas similares a muchos otros problemas y, por lo general, solo pueden ser analizadas por programadores que tengan acceso al código fuente del programa. Sin embargo, muchas personas están acostumbradas a describir cualquier aumento no deseado en el uso de memoria como una pérdida de memoria, aunque esto no es estrictamente exacto.

En términos generales, pérdidas de memoria

se refiere a pérdidas de memoria del montón. La memoria del montón se refiere a la memoria asignada por el programa desde el montón, de cualquier tamaño (el tamaño del bloque de memoria se puede determinar durante la ejecución del programa), y la memoria liberada debe mostrarse después de su uso. Las aplicaciones generalmente usan funciones como malloc, realloc, new, etc. para asignar una parte de la memoria del montón. Después de su uso, el programa debe ser responsable de llamar a free o eliminar en consecuencia para liberar el bloque de memoria. p>

Si se guarda y no se puede volver a utilizar, decimos que esta memoria pierde.

Las pérdidas de memoria se pueden dividir en 4 categorías:

1.

Pérdidas de memoria recurrentes. El código con pérdidas de memoria se ejecutará varias veces, lo que provocará una pérdida de memoria cada vez que se ejecute.

2.

Pérdidas de memoria ocasionales. El código que causa pérdidas de memoria solo ocurrirá bajo ciertas circunstancias u operaciones. Frecuentes y esporádicas son relativas. En determinadas circunstancias, lo ocasional puede volverse común. Por tanto, el entorno de prueba y los métodos de prueba son cruciales para detectar pérdidas de memoria.

3.

Pérdida de memoria única. El código que causa una pérdida de memoria solo se ejecutará una vez o, debido a fallas algorítmicas, siempre habrá solo un bloque de memoria perdido. Por ejemplo, si se asigna memoria en el constructor de una clase, pero no se libera en el destructor, la pérdida de memoria solo ocurrirá una vez.

4.

Pérdida de memoria implícita. El programa asigna memoria continuamente mientras se ejecuta, pero no la libera hasta el final. Estrictamente hablando, aquí no hay pérdida de memoria, porque el programa finalmente libera toda la memoria solicitada. Pero

Para un programa de servidor que necesita ejecutarse durante días, semanas o incluso meses, no liberar memoria a tiempo también puede provocar el agotamiento de toda la memoria del sistema. Por lo tanto, a este tipo de pérdida de memoria lo llamamos pérdida de memoria implícita.

Simple:

Una pérdida de memoria significa olvidarse de liberar la memoria utilizada, lo que hace que el siguiente uso sea riesgoso.

El desbordamiento de la memoria significa que un determinado espacio de memoria no puede contener todos los datos que deben almacenarse, lo que provoca que los datos de la memoria se desborden.

Se explica principalmente en las siguientes partes, con respecto a los conceptos de memoria y pérdidas y desbordamientos de memoria, distinguiendo pérdidas de memoria y desbordamientos de memoria; dividiendo áreas de memoria, entendiendo el mecanismo de reciclaje de GC, enfocándose en cómo monitorear y descubrir la memoria; problema, además, analizar el problema y cómo solucionar el problema de la memoria.

A continuación comienza el contenido de este artículo:

La primera parte del concepto

Como todos sabemos, la memoria en Java es administrada por el Java máquina virtual en sí. No es que C necesite ser liberado por sí mismo. En términos generales, la asignación de memoria de Java se divide en dos partes, una es el montón de datos y la otra es la pila. Cuando un programa se está ejecutando, generalmente asigna un montón de datos y coloca en él variables temporales locales. El ciclo de vida está relacionado con el proceso.

Pero si el programador declara una variable estática, se ejecutará directamente en la pila. Si el proceso se destruye, la variable estática no necesariamente se destruirá.

Además, para garantizar que la memoria Java no se desborde, Java tiene un mecanismo de recolección de basura.

System.gc(), el mecanismo de recolección de basura, se refiere al jvm utilizado para liberar la memoria ocupada por objetos que ya no se usan. El lenguaje Java no requiere que la JVM tenga gc ni especifica cómo funciona gc. El propósito de la recolección de basura es eliminar objetos que ya no se utilizan. El gc determina si se debe recopilar un objeto determinando si un objeto activo hace referencia a él.

Entre ellos, el desbordamiento de memoria significa que la memoria de la máquina virtual Java que usted solicita asignar excede lo que el sistema puede brindarle y el sistema no puede satisfacer la demanda, por lo que se produce un desbordamiento.

Pérdida de memoria significa que solicita al sistema que le asigne memoria para su uso (nueva), pero no la devuelve (elimina) después de usarla. Como resultado, no puede acceder a la memoria que solicitó nuevamente.

p>

Pregunta: la memoria asignada de este bloque ya no se puede utilizar. A medida que la memoria del servidor continúa consumiéndose, hay cada vez más memoria inutilizable disponible y el sistema no puede volver a asignarla a los programas requeridos. , lo que da como resultado Ceder el paso.

A medida que avanza, el programa se irá quedando sin memoria y se desbordará.

Principio de la Parte 2

Recolección de basura JAVA y división del área de memoria

En la especificación de la máquina virtual Java, se mencionan los siguientes tipos de espacios de memoria:

◇ Memoria de pila (Stack): privada para cada hilo.

◇ Memoria de montón (Heap): común a todos los hilos.

◇Área de método: es un poco como el "segmento de código de proceso" mencionado a menudo en el pasado. Almacena la información de reflexión de cada clase cargada, el código de la función de clase, las constantes de tiempo de compilación y. otra información.

◇ Pila de métodos nativos: se utiliza principalmente para código nativo en JNI y rara vez participa en tiempos normales.

Java utiliza memoria de montón. El montón de Java es un área de datos en tiempo de ejecución desde la cual las instancias (objetos) de las clases asignan espacio. El montón de la máquina virtual Java (JVM) almacena todos los objetos creados por la aplicación en ejecución. La "recolección de basura" está relacionada principalmente con la memoria del montón (Heap).

El concepto de recolección de basura es el proceso mediante el cual la Máquina Virtual JAVA (JVM) recupera la memoria de los objetos a los que ya no se hace referencia. Generalmente, pensamos que el estado del objeto al que se hace referencia es "vivo", mientras que el estado del objeto que no se ha aplicado o no se puede obtener el atributo de referencia es "muerto". La recolección de basura es el proceso de liberar la memoria de objetos en estado "muerto". Las reglas y algoritmos de recolección de basura se aplican dinámicamente a la aplicación en ejecución y se reciclan automáticamente.

El recolector de basura de JVM adopta una estrategia de reciclaje generacional, escaneando y reciclando objetos jóvenes (generación

joven) con mayor frecuencia. Esto se denomina recolección menor, mientras que la frecuencia de verificación y reciclaje. Los objetos antiguos (vieja generación) son mucho más bajos, lo que se denomina colección principal. De esta manera, no es necesario verificar todos los objetos en la memoria cada vez que se usa GC. Esta estrategia favorece la observación y el reciclaje en tiempo real.

(Sun JVM 1.3

Hay dos métodos más básicos de recopilación de memoria: uno se llama copiar o eliminar. Después de mover todos los objetos supervivientes a otra parte de la memoria, toda la memoria del bloque se puede reciclar Este método es eficiente, pero requiere una cierta cantidad de memoria libre y la copia también es costosa. El otro método se llama marca-compacto. Los objetos se marcan y luego se mueven juntos en un gran bloque de memoria. la memoria se puede reciclar. Este método no requiere espacio adicional, pero es relativamente más lento.

)

Algunos objetos se crean con solo un ciclo de vida corto, como los iteradores y los locales. variables. Otros objetos se crean con un ciclo de vida largo, como los objetos persistentes.

La estrategia generacional del recolector de basura es dividir el área de memoria en varias generaciones y luego asignar uno o más bloques de memoria a cada generación. Cuando una de las generaciones agota la memoria asignada, la JVM realizará una operación de GC local (también llamada colección menor) en el área de memoria asignada para reciclar objetos en el estado "muerto". memoria ocupada. La GC parcial suele ser mucho más rápida que la GC completa.

La JVM define dos generaciones, la generación joven (a veces llamada "guardería") y la generación anterior. La generación joven incluye

"espacio Edén" y dos "espacios de supervivientes". Cuando se inicializa la memoria virtual, todos los objetos se asignarán al espacio Eden

y la mayoría de los objetos también se liberarán en esta área. Al realizar una GC menor, la VM moverá los objetos restantes inéditos del espacio del Edén a uno de los espacios de supervivientes. Además, la VM también moverá objetos que hayan sobrevivido durante mucho tiempo en los espacios de supervivientes al espacio "titular" de la generación anterior. Cuando se completa la generación titular, se producirá GC completo y será relativamente lento porque el contenido reciclado incluye todos los objetos vivos. pemanet

La generación incluye todos los objetos de datos relativamente estables utilizados por la propia máquina virtual Java, como clases y métodos de objetos.

En cuanto a la división de generaciones, puedes obtener una descripción general en la siguiente figura:

Resumen de la tercera parte

El desbordamiento de memoria se debe principalmente a ciertos Errores al escribir código La aplicación de métodos y clases no es razonable, o no se estima que los objetos temporales ocuparán una gran cantidad de memoria, o se colocan demasiados datos en la caché de JVM, o la presión de rendimiento es alta, lo que genera mensajes. Como resultado, durante las pruebas de rendimiento, se generó una gran cantidad de objetos temporales y el GC no los recicló de manera efectiva o incluso no los recicló en absoluto, lo que resultó en un espacio de memoria insuficiente y un desbordamiento de la memoria.

Si antes de la codificación, se estima el uso de la memoria y se evalúan los datos colocados en la memoria para garantizar que la información útil se libere lo antes posible y que el GC pueda reciclar la información inútil, esto es hasta cierto punto Hasta cierto punto se pueden evitar los problemas de desbordamiento de la memoria.