Docs Menu
Docs Home
/ /
Archivos del reino

Reducir el tamaño de archivo de Realm - Swift SDK

El tamaño de un archivo de realm siempre es mayor que el tamaño total de los objetos almacenados en él. Esta arquitectura permite obtener algunas de las grandes ventajas de realm en cuanto a rendimiento, concurrencia y seguridad.

Realm escribe datos nuevos en el espacio no utilizado registrado dentro de un archivo. En algunas situaciones, el espacio no utilizado puede representar una parte significativa de un archivo de realm. El comportamiento predeterminado de Realm es compactar automáticamente un archivo de realm para evitar que crezca demasiado. Puede usar estrategias de compactación manual cuando la compactación automática no sea suficiente para su caso de uso o si utiliza una versión del SDK que no la tenga.

Generalmente, un archivo realm ocupa menos espacio en disco que una base de datos SQLite comparable. El crecimiento inesperado del archivo puede deberse a que Atlas App Services utiliza datos obsoletos. Estos factores pueden afectar el tamaño del archivo:

  • Transacciones de fijación

  • Enhebrado

  • Colas de despacho

Cuando consideres reducir el tamaño del archivo mediante la compactación, hay un par de cosas a tener en cuenta:

  • La compactación puede ser una operación que consuma muchos recursos

  • La compactación puede bloquear el hilo de la interfaz de usuario

Debido a estos factores, probablemente no quieras compactar un reino cada vez que lo abras, sino que debes considerar Cuándo compactar un dominio. Esto varía según la plataforma y los patrones de uso de la aplicación. Al decidir cuándo compactar, tenga en cuenta las limitaciones de tamaño de los archivos de iOS.

Realm vincula la duración de las transacciones de lectura con la duración de la memoria de las instancias de Realm. Evite fijar transacciones antiguas de Realm. Utilice reinos con actualización automática y encierre el uso de las API de Realm desde subprocesos en segundo plano en grupos de liberación automática explícitos.

Realm actualiza la versión de tus datos a la que accede al inicio de una iteración del ciclo de ejecución. Si bien esto te brinda una vista coherente de tus datos, tiene implicaciones en el tamaño del archivo.

Imagínese este escenario:

  • Hilo A: Leer algunos datos de un reino y luego bloquear el hilo en una operación de ejecución larga.

  • Hilo B: Guarda datos en otro hilo.

  • Hilo A: La versión del hilo de lectura no se actualiza. Realm debe almacenar versiones intermedias de los datos, cuyo tamaño aumenta con cada escritura.

Para evitar este problema, llama a invalidate() en el dominio. Esto le indica que ya no necesitas los objetos que has leído. Esto evita que el dominio tenga que rastrear versiones intermedias de esos objetos. La próxima vez que accedas, el dominio tendrá la versión más reciente de los objetos.

También puedes utilizar estos dos métodos para compactar tu Reino:

Tip

Al acceder a Realm mediante Grand Central DispatchEs posible que observe un crecimiento de archivos similar. Es posible que el grupo de liberación automática de una cola de despacho no se vacíe inmediatamente tras ejecutar el código. Realm no puede reutilizar versiones intermedias de los datos hasta que el grupo de despacho desasigne el objeto realm. Utilice un grupo de liberación automática explícito al acceder a realm desde una cola de despacho.

Nuevo en la versión 10.35.0.

El SDK compacta automáticamente los archivos Realm en segundo plano reasignando continuamente los datos dentro del archivo y eliminando el espacio no utilizado. La compactación automática es suficiente para minimizar el tamaño de los archivos Realm en la mayoría de las aplicaciones.

La compactación automática comienza cuando el espacio no utilizado del archivo es más del doble del tamaño de los datos del usuario. La compactación automática solo se realiza cuando no se accede al archivo.

La compactación manual se puede utilizar para aplicaciones que requieren una gestión más estricta del tamaño de archivo o que utilizan una versión anterior del SDK que no admite la compactación automática.

La compactación manual de Realm funciona de la siguiente manera:

  1. Leyendo todo el contenido del archivo del reino

  2. Escribir el contenido en un nuevo archivo en una ubicación diferente

  3. Reemplazar el archivo original

Si el archivo contiene muchos datos, esta puede ser una operación costosa.

Utilice shouldCompactOnLaunch() (Swift) o shouldCompactOnLaunch (Objective-C) en el objeto de configuración de un dominio para compactarlo. Especifique las condiciones para ejecutar este método, como:

  • El tamaño del archivo en el disco

  • La cantidad de espacio libre que contiene el archivo

Para obtener más información sobre las condiciones a ejecutar en el método, consulte: Consejos para usar la compactación manual.

Importante

Es posible que no se produzca compactación

La compactación no puede ocurrir mientras se accede a un reino, independientemente de cualquier configuración.

RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
config.shouldCompactOnLaunch = ^BOOL(NSUInteger totalBytes, NSUInteger usedBytes) {
// totalBytes refers to the size of the file on disk in bytes (data + free space)
// usedBytes refers to the number of bytes used by data in the file
// Compact if the file is over 100MB in size and less than 50% 'used'
NSUInteger oneHundredMB = 100 * 1024 * 1024;
return (totalBytes > oneHundredMB) && ((double)usedBytes / totalBytes) < 0.5;
};
NSError *error = nil;
// Realm is compacted on the first open if the configuration block conditions were met.
RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:&error];
if (error) {
// handle error compacting or opening Realm
}
let config = Realm.Configuration(shouldCompactOnLaunch: { totalBytes, usedBytes in
// totalBytes refers to the size of the file on disk in bytes (data + free space)
// usedBytes refers to the number of bytes used by data in the file
// Compact if the file is over 100MB in size and less than 50% 'used'
let oneHundredMB = 100 * 1024 * 1024
return (totalBytes > oneHundredMB) && (Double(usedBytes) / Double(totalBytes)) < 0.5
})
do {
// Realm is compacted on the first open if the configuration block conditions were met.
let realm = try Realm(configuration: config)
} catch {
// handle error compacting or opening Realm
}

Cuando usa la sintaxis Swift async/await para abrir un reino de forma asincrónica, puede compactar un reino en segundo plano.

func testAsyncCompact() async {
let config = Realm.Configuration(shouldCompactOnLaunch: { totalBytes, usedBytes in
// totalBytes refers to the size of the file on disk in bytes (data + free space)
// usedBytes refers to the number of bytes used by data in the file
// Compact if the file is over 100MB in size and less than 50% 'used'
let oneHundredMB = 100 * 1024 * 1024
return (totalBytes > oneHundredMB) && (Double(usedBytes) / Double(totalBytes)) < 0.5
})
do {
// Realm is compacted asynchronously on the first open if the
// configuration block conditions were met.
let realm = try await Realm(configuration: config)
} catch {
// handle error compacting or opening Realm
}
}

A partir de las versiones 10.15.0 y 10.16.0 del SDK de Realm Swift, muchas de las API de Realm admiten la sintaxis async/await de Swift. Los proyectos deben cumplir estos requisitos:

Versión del SDK de Swift
Requisito de versión Swift
Sistema operativo compatible

10.25.0

Swift 5.6

iOS 13.x

10.15.0 o 10.16.0

Swift 5.5

iOS 15.x

Si su aplicación accede a Realm en un async/await contexto, marque el código con @MainActor para evitar fallas relacionadas con subprocesos.

Puedes guardar una copia compactada (y opcionalmente cifrada) de un dominio en otra ubicación de archivo con el método Realm.writeCopy(toFile:encryptionKey:). El archivo de destino no puede existir previamente.

Importante

Evite llamar a este método dentro de una transacción de escritura. Si se llama dentro de una transacción de escritura, este método copia los datos más recientes. Esto incluye cualquier cambio no confirmado realizado en la transacción antes de llamarlo.

Compactar un reino puede ser una operación costosa que puede bloquear el hilo de la interfaz de usuario. Tu aplicación no debería compactar cada vez que abras un reino. En su lugar, intenta optimizar la compactación para que lo haga con la frecuencia justa para evitar que el tamaño del archivo crezca demasiado. Si tu aplicación se ejecuta en un entorno con recursos limitados, podrías querer compactar cuando alcances un tamaño de archivo determinado o cuando este afecte negativamente al rendimiento.

Estas recomendaciones pueden ayudarle a optimizar la compactación manual para su aplicación:

  • Establezca el tamaño máximo de archivo en un múltiplo del tamaño promedio de su estado de dominio. Si el tamaño promedio de su estado de dominio es de 10MB, puede establecer el tamaño máximo de archivo en 20MB o 40MB, según el uso previsto y las limitaciones del dispositivo.

  • Como punto de partida, compacte los dominios cuando más del 50% del tamaño del archivo del dominio ya no esté en uso. Divida los bytes utilizados actualmente entre el tamaño total del archivo para determinar el porcentaje de espacio utilizado. Luego, verifique que sea menor al 50%. Esto significa que más del 50% del tamaño del archivo del dominio es espacio sin usar, y es un buen momento para compactar. Después de experimentar, puede que un porcentaje diferente funcione mejor para su aplicación.

Estos cálculos podrían verse así en su devolución de llamada shouldCompactOnLaunch:

// Set a maxFileSize equal to 20MB in bytes
let maxFileSize = 20 * 1024 * 1024
// Check for the realm file size to be greater than the max file size,
// and the amount of bytes currently used to be less than 50% of the
// total realm file size
return (realmFileSizeInBytes > maxFileSize) && (Double(usedBytes) / Double(realmFileSizeInBytes)) < 0.5

Experimente con las condiciones para encontrar el equilibrio adecuado entre la frecuencia con la que debe compactar los archivos de reino en su aplicación.

Un archivo realm grande puede afectar el rendimiento y la fiabilidad de tu aplicación. Ningún archivo realm puede superar la cantidad de memoria que tu aplicación podría asignar en iOS. Este límite depende del dispositivo y de la fragmentación de la memoria en ese momento.

Si necesita almacenar más datos, asigne nombres a varios archivos de reino.

  • La arquitectura de Realm permite beneficios relacionados con subprocesos, pero puede generar un crecimiento del tamaño de los archivos.

  • La compactación automática gestiona el crecimiento del tamaño del archivo cuando no se accede a él.

  • Se pueden utilizar estrategias de compactación manual como shouldCompactOnLaunch() cuando la compactación automática no satisface las necesidades de la aplicación.

  • La compactación no puede ocurrir si otro proceso está accediendo al reino.

  • Puede compactar un realm en segundo plano cuando utiliza la sintaxis asíncrono/await.

Volver

Agrupa un reino

En esta página