한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

Libro blanco del lag en juegos › L1 Proceso del juego en el cliente

Recolección de basura (GC) en el cliente Client GC (Unity C#, Unreal, Lua)

ID de la causa cg-gc · Responsable principal Desarrollo de cliente (Equipo de desarrollo)

Abrir la ficha interactiva con gráficos y simulaciones →

El juego entero se detiene mientras se recupera la memoria ya usada y desechada (basura). Lo característico son tirones a intervalos regulares.

Por qué En cada frame se crean y se desechan cadenas de texto, arrays y listas temporales → Efecto Cuando se acumula basura, el GC detiene el hilo principal para liberarla → En pantalla Tirones regulares cada pocos segundos o cada varias decenas de segundos

Síntomas
Tirones, Congelamiento
Factores
Detención
A quién afecta
Solo yo
Cuándo
A intervalos regulares, Cuando se junta mucha gente
Responsable
Responsable principal Desarrollo de cliente (Equipo de desarrollo)
Tareas (Equipo de desarrollo)
Reducir las asignaciones (evitar concatenar cadenas, LINQ y capturas en lambdas), usar pools de objetos, mantener activado el GC incremental (opción predeterminada desde Unity 2020), forzar el GC por adelantado en momentos en que una pausa no molesta, como las pantallas de carga.
Cifras de referencia
Normalmente de varios ms a 100 ms por recolección, y más en teléfonos de gama baja o en juegos que usan mucha memoria (en la simulación, unos 150–170 ms). El GC de Unity revisa todo el heap cada vez que se ejecuta, así que cuanta más memoria usa el juego, más dura.
En el gráfico
Picos periódicos · Tiempo de frame, momentos de ejecución del GC
Dónde mirar
En una build de desarrollo, los marcadores GC.Collect y GC.Alloc del Profiler de Unity. En Unreal, stat GC y stat Hitches (registra en el log los frames que superan el tiempo fijado en t.HitchFrameTimeThreshold)
Se confirma si
Cada frame con pico tiene un tramo de GC.Collect de duración parecida a la del pico, y los picos se repiten a intervalos regulares de unos segundos a varias decenas de segundos. Donde hay mucha gente, GC.Alloc por frame aumenta
Se descarta si
Si los frames con pico no tienen tramo de GC: “Carga síncrona y compilación de shaders en el hilo principal” o “Carga de renderizado de multitudes”
Se verifica con
Requiere logs y métricas del servidor o el cliente del juego
Para saber más
Es habitual en clientes que usan C#, como los de Unity. Los principales culpables son el código que vuelve a crear en cada frame las cadenas del log de combate, los números de daño y los textos de la UI. Si los tirones solo aparecen donde hay mucha gente, hay código que genera basura en proporción al número de jugadores. El GC incremental reparte la recolección en pequeñas porciones por frame (3 ms por defecto en Unity), pero si el juego genera basura más rápido de lo que se recolecta, al final se detiene de golpe. Unreal Engine también tiene su propio GC, que limpia los objetos del juego que ya no se usan. Depende de la versión del motor y de la configuración, pero con los valores predeterminados se ejecuta aproximadamente cada minuto y puede provocar un tirón por minuto. En los clientes cuyas reglas de juego están escritas en un lenguaje de scripting como Lua, el GC de ese lenguaje también se ejecuta por separado.

Fuentes

  1. Garbage collection modes Unity
    El GC incremental es la opción predeterminada y reparte la recolección entre varios frames; si se desactiva, el hilo principal se detiene mientras se revisa todo el heap, y la pausa puede llegar a cientos de ms
  2. Scripting.GarbageCollector.CollectIncremental Unity
    El objetivo predeterminado del tiempo que el GC incremental usa en cada porción (time slice) es de 3 ms (incrementalTimeSliceNanoseconds)
  3. Garbage Collection Settings in the Unreal Engine Project Settings Epic Games
    Ajuste que hace que el GC de Unreal se ejecute a un intervalo fijo (Time Between Purging Pending Kill Objects, en segundos). Este documento no indica el valor predeterminado
  4. Profiler markers reference Unity
    GC.Collect: tramo en que el código del programa se detiene durante la recolección de basura (de menos de 1 ms a cientos de ms); GC.Alloc: asignación en el heap administrado
  5. Stat Commands in Unreal Engine Epic Games
    stat GC (estadísticas de recolección de basura), stat Hitches (registra en el log los frames que superan t.HitchFrameTimeThreshold)

Ver también

Misma capa: L1 Proceso del juego en el cliente

Causas de otras capas con el mismo síntoma (Tirones)

Ver la ficha interactiva con gráficos y simulaciones