es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

ruby: ¿Podemos sobrevivir a NoMemoryError?

Cuando Ruby se queda sin memoria para sus asignaciones internas, genera un error de NoMemoryError.

Podemos capturar este error e incluso realizar operaciones simples, pero parece que si tratamos de continuar después de la recolección de basura, eventualmente nos encontraremos con un problema fatal de asignación de memoria, que en mi sistema Linux se ve así:

[FATAL] no se pudo asignar memoria

Sospecho que en este punto mi sistema operativo se queja de que Ruby se quedó sin memoria en lugar de que Ruby lo detecte.

Lo que no entiendo es que hay muchos casos en los que deberíamos poder continuar después de rescatar un NoMemoryError (y por lo tanto, abandonar la asignación que causó el error), pero parece que Ruby nunca limpia el desastre. Un ejemplo simple es causar (y rescatar) un NoMemoryError al desplazar un número demasiado grande. Por ejemplo:

begin
a = 1<<10000000000000 puts "Respuesta calculada de alguna manera" rescue NoMemoryError => e
puts “RESCATE: sin memoria”
end
puts “Finalizada la primera sección begin/rescue/end”

GC.start # Esto es en vano

begin
a = 1<<10000000000000 puts "Respuesta calculada de alguna manera" rescue NoMemoryError => e
puts “RESCATE: sin memoria”
end
puts “Finalizada la segunda sección begin/rescue/end”

Capturamos el primero, lo cual parece que debería recuperar la memoria a partir de lo que presumo que es un desbordamiento de BigNum, pero esa memoria nunca vuelve, ni siquiera por parte de la recolección de basura. Entonces, la próxima vez que intentamos asignar una gran cantidad de memoria (en este caso, con el mismo problema), en realidad nos encontramos con un error fatal. La salida completa:

RESCATE: sin memoria
Finalizada la primera sección begin/rescue/end
[FATAL] no se pudo asignar memoria

¿Hay alguna forma de reparar el estado después de que Ruby haya generado un NoMemoryError si rescata (y por lo tanto, aborta) la operación que consumió demasiada memoria?

Da la sensación de que esto podría ser un problema con el recolector de basura, posiblemente no marcando adecuadamente la memoria como ya no utilizada cuando hacemos un rescate, lo que me hace pensar que podría haber un error en el recolector de basura que esto está revelando.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Ruby y Asignación de Memoria

    Ruby genera un error NoMemoryError cuando se queda sin memoria para sus asignaciones internas. Este error se puede capturar y realizar operaciones simples. Sin embargo, continuar después de la recolección de basura, incluso después de capturar el error, puede llevar a problemas fatales de asignación de memoria. El mensaje de error fatal puede ser generado por el sistema operativo, indicando falta de memoria, en lugar de ser generado por Ruby en sí.

    El problema en este caso parece ser que Ruby no limpia el desorden de memoria después de capturar el error, como debería. Por ejemplo, capturar un NoMemoryError desplazando un número que es demasiado grande e intentar ejecutar algún código después de eso, sin liberar la memoria adecuadamente, puede llevar a errores fatales de asignación de memoria. Incluso ejecutar la recolección de basura no parece ser efectivo para resolver este problema.

    Es posible que el Recolector de Basura no esté marcando correctamente la memoria como ya no utilizada cuando ocurre un rescate, lo cual indica un posible error. Por lo tanto, el estado de la asignación de memoria de Ruby después de capturar un NoMemoryError no está del todo claro, lo que conduce a más problemas con la gestión de memoria.

Comments are closed.