← Blog

Cómo evita PrintStash quedarse sin RAM con mallas grandes

Una mirada técnica a las estimaciones de triángulos, presupuestos de memoria con cgroups, concurrencia de renderizado y salto seguro de previsualizaciones.

desarrollorendimientoanálisis a fondo

PrintStash evita quedarse sin RAM con mallas grandes estimando el número de triángulos de una malla antes de cargarla, y saltándose después la generación de geometría y de miniatura para cualquier cosa por encima de VAULT_MESH_MAX_RENDER_TRIANGLES, cuyo valor por defecto es 2.000.000. El modelo se sigue indexando y se puede buscar; lo único que falta es su previsualización.

Este comportamiento salió de un fallo temprano. Los primeros escaneos de volúmenes compartidos llegaron a una malla inusualmente densa, el uso de memoria se disparó durante la generación de la miniatura y el contenedor murió. En un servidor doméstico más pequeño el mismo archivo podía, en su lugar, empujar al anfitrión a un swap intenso. El archivo seguía teniendo que aparecer en la biblioteca, y saltarse su previsualización dejó que el resto del escaneo terminara.

Estimar antes de cargar

Un STL normal puede ser fácil de previsualizar. Un escaneo o una celosía pueden contener millones de triángulos y necesitar mucha más memoria de lo que sugiere su tamaño de archivo. Parsearlo para descubrir que es demasiado grande echa a perder el sentido de una comprobación de seguridad.

La estimación se ejecuta antes de que un formato de malla compatible llegue al cargador completo, así que la decisión cuesta la lectura de una cabecera en lugar de un parseo entero. Un archivo por encima del límite de triángulos se indexa sin generar geometría ni miniatura, aunque un 3MF grande puede conservar su previsualización incrustada.

VAULT_MESH_MAX_LOAD_MB aporta un segundo techo, independiente del formato, cuando no hay disponible una estimación fiable de triángulos. Su valor por defecto es 200 MB.

El presupuesto sigue al contenedor

La RAM del anfitrión no es el número correcto cuando Docker tiene un límite de cgroup más pequeño. PrintStash detecta la memoria disponible para el proceso y deriva de VAULT_MESH_MEMORY_BUDGET_FRACTION un tope de triángulos específico del formato.

La fracción por defecto es 0.5. El límite calculado se combina con el tope fijo de triángulos, así que un contenedor pequeño se salta trabajo que uno más grande puede renderizar sin riesgo. Esto no requiere ningún perfil por anfitrión en una instalación normal.

El renderizado va en serie y por bloques

Las importaciones masivas pueden encolar muchas tareas de fondo. VAULT_MAX_RENDER_JOBS limita cuántos renderizados costosos de malla se ejecutan a la vez, y su valor por defecto es uno. Si se aumenta la concurrencia, el presupuesto de memoria se reparte entre esos trabajos.

El rasterizador por software procesa las caras en bloques controlados por VAULT_MESH_RENDER_FACE_CHUNK_SIZE. Los arrays temporales escalan por tanto con el bloque y no con el número total de caras. Los arrays float32 reducen aún más la huella sin afectar de forma apreciable a una miniatura pequeña.

Cuando un archivo termina, el worker pide al asignador del sistema que devuelva al kernel las arenas liberadas, allí donde malloc_trim está disponible. Eso evita que un escaneo largo se quede con todos los máximos anteriores.

Qué ve la persona que lo usa

Cuando se salta una previsualización, el modelo sigue indexado y se puede buscar. El archivo original no se modifica, y sus metadatos se pueden seguir guardando allí donde la extracción no requirió cargar la geometría completa. Los logs explican qué límite impidió el renderizado.

La mayoría de las instalaciones deberían quedarse con los valores por defecto. En un anfitrión con poca memoria, baja la fracción de memoria o los topes fijos antes de aumentar el swap de Docker. En un anfitrión grande, súbelos solo después de medir una importación representativa.

Los ajustes actuales y sus implicaciones de memoria están documentados en la referencia de configuración.