Scala for Backend Engineering & Functional Programming · Lección

Gestión de memoria y ajuste del GC

Profundice en la gestión de memoria de la JVM, la recolección de basura y las técnicas para optimizar el uso de memoria en Scala.

Lección 2 de 311 pasos

Gestión de memoria y ajuste del GC es una lección gratuita de Scala for Backend Engineering & Functional Programming en CoddyKit. Esta es la lección 2 de 3. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Scala for Backend Engineering & Functional Programming, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Scala for Backend Engineering & Functional Programming incluye 3 lecciones en total.

Introducción a la memoria y el GC de la JVM

¡Le damos la bienvenida! En esta lección, profundizaremos en cómo la máquina virtual de Java (JVM) administra la memoria, algo especialmente importante para las aplicaciones de Scala.

  • Comprender la memoria le ayuda a escribir código eficiente y de alto rendimiento.
  • Exploraremos la recolección de basura (GC), el administrador automático de memoria de la JVM.
  • Una gestión adecuada de la memoria evita problemas habituales, como los errores de falta de memoria.

El heap: almacenamiento de objetos

El heap es la mayor área de memoria de la JVM y es donde residen todos los objetos creados por su aplicación de Scala. Esto incluye instancias de clases, matrices y la mayoría de las estructuras de datos.

El heap se comparte entre todos los hilos de su aplicación. Su tamaño influye directamente en la cantidad de objetos que el programa puede mantener simultáneamente.

Pila frente a heap: diferencias clave

Mientras el Heap contiene objetos, la Stack almacena variables locales (especialmente tipos primitivos y referencias a objetos) y marcos de llamadas a métodos. Cada subproceso tiene su propia Stack.

  • Heap: Almacena objetos, es compartido y lo gestiona el GC.
  • Stack: Almacena llamadas a métodos y variables locales; es específica de cada subproceso y se gestiona automáticamente cuando los métodos entran y salen.

Comprender esta distinción es fundamental para depurar problemas de memoria.

Conceptos básicos de Garbage Collection

Garbage Collection (GC) es el proceso automático de la JVM que busca y recupera la memoria ocupada por objetos que la aplicación ya no puede «alcanzar».

En lugar de liberar la memoria manualmente (como en C++), Scala (al igual que Java) depende del GC para evitar fugas de memoria y simplificar el desarrollo. La idea fundamental es «mark and sweep»: marcar los objetos alcanzables y después eliminar el resto.

Explicación del GC generacional

La mayoría de los GC modernos utilizan un enfoque generacional, que divide el Heap en áreas según la antigüedad de los objetos:

  • Young Generation: Aquí se asignan los objetos nuevos. La mayoría de los objetos dejan de existir rápidamente en esta generación.
  • Old Generation: Los objetos que sobreviven a varios GC en la Young Gen se promocionan a esta generación.

Esto permite ejecutar GC más frecuentes y rápidos en la Young Gen (Minor GC), y GC menos frecuentes y más lentos en la Old Gen (Major GC).

Colecciones y memoria en Scala

El énfasis de Scala en la inmutabilidad y la programación funcional suele implicar la creación de muchos objetos de corta duración, especialmente durante las transformaciones de colecciones.

El GC está optimizado para este escenario. Veamos un ejemplo de creación de objetos temporales al procesar una lista:

object Main {
  def main(args: Array[String]): Unit = {
    println("Creating and transforming a list...")
    val originalList = (1 to 100000).toList // ~100k objects
    val transformedList = originalList.map(x => x * 2).filter(_ % 3 == 0)
    println(s"Transformed list size: ${transformedList.size}")
    // originalList and intermediate lists from map are now eligible for GC
    println("Intermediate objects are efficiently managed by GC.")
  }
}

Situaciones habituales de fugas de memoria

Incluso con GC, pueden producirse fugas de memoria cuando las referencias fuertes mantienen vivos los objetos de forma involuntaria. Algunas situaciones habituales en Scala son:

  • Cachés de larga duración: Almacenar objetos indefinidamente en un mapa mutable global.
  • Closures: Una closure (literal de función) que captura un objeto grande cuya duración supera el ámbito previsto de la closure.
  • Recursos sin cerrar: No cerrar correctamente los descriptores de archivos o las conexiones de red.

Referencias débiles para el almacenamiento en caché

Para los cachés en los que desea que el GC recupere la memoria si el objeto solo está referenciado por el caché, utilice java.lang.ref.WeakReference.

Una WeakReference no impide que su objeto referenciado sea recopilado por el garbage collector. Si las únicas referencias restantes a un objeto son referencias débiles, el objeto pasa a ser apto para el GC.

import java.lang.ref.WeakReference

object Main {
  def main(args: Array[String]): Unit = {
    var largeData: Array[Byte] = new Array[Byte](1024 * 1024) // 1MB
    val weakCacheEntry = new WeakReference(largeData)

    println(s"Data exists via weak ref: ${weakCacheEntry.get() != null}")

    largeData = null // Remove the strong reference

    System.gc() // Hint to the JVM to run GC
    Thread.sleep(100) // Give GC time to run

    println(s"Data collected (possibly): ${weakCacheEntry.get() == null}")
    println("WeakReference allows GC to clean up if no strong references remain.")
  }
}

Indicadores básicos de la JVM para ajustar el GC

Aunque el GC es automático, puede ajustar su comportamiento mediante argumentos de la JVM. Entre los indicadores principales se incluyen:

  • -Xmx: Establece el tamaño máximo del heap de Java (por ejemplo, -Xmx4g para 4 gigabytes).
  • -Xms: Establece el tamaño inicial del heap de Java (por ejemplo, -Xms512m para 512 megabytes).
  • -XX:+UseG1GC: Especifica el recolector Garbage-First (G1), una opción moderna y habitual.

Ajustar estos indicadores puede afectar considerablemente al rendimiento de la aplicación y al uso de memoria.

Compruebe sus conocimientos

¿Cuáles de las siguientes afirmaciones sobre la gestión de memoria de la JVM y Garbage Collection son VERDADERAS?

Resumen: memoria y GC

¡Buen trabajo! Ha explorado los fundamentos de la gestión de memoria de la JVM y Garbage Collection:

  • El Heap contiene objetos, mientras que la Stack contiene llamadas a métodos y variables locales.
  • El GC recupera automáticamente la memoria de los objetos inalcanzables.
  • Comprender el GC generacional (generaciones Young y Old) ayuda a optimizar el rendimiento.
  • Preste atención a las fugas de memoria y utilice herramientas como WeakReference para necesidades específicas de almacenamiento en caché.
  • Los indicadores básicos de la JVM, como -Xmx y -Xms, controlan el tamaño del heap.

A continuación, profundizaremos en las herramientas de profiling para identificar cuellos de botella.

Gratis para empezar

Aprende Scala con un tutor de IA — gratis

Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.

Cursos
39
Lecciones
143

Preguntas frecuentes

¿La lección «Gestión de memoria y ajuste del GC» es gratis?

Sí — el texto completo de «Gestión de memoria y ajuste del GC» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Scala for Backend Engineering & Functional Programming, actualiza a CoddyKit PRO. El curso de Scala for Backend Engineering & Functional Programming incluye 3 lecciones en total.

¿Qué aprenderé en «Gestión de memoria y ajuste del GC»?

Profundice en la gestión de memoria de la JVM, la recolección de basura y las técnicas para optimizar el uso de memoria en Scala. Practicas Scala for Backend Engineering & Functional Programming con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Scala for Backend Engineering & Functional Programming?

No se requiere experiencia previa. Scala for Backend Engineering & Functional Programming en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 3.

¿Cuánto tiempo toma la lección «Gestión de memoria y ajuste del GC»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Scala for Backend Engineering & Functional Programming?

Sí. Cada lección de Scala for Backend Engineering & Functional Programming incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Creación de perfiles de aplicaciones Scala
  2. Gestión de memoria y ajuste del GC
  3. Optimización de código concurrente
← Volver a Scala for Backend Engineering & Functional Programming