Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /
Realm Files

Reduce Realm File Size - Swift SDK

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

Realm writes new data within unused space tracked inside a file. In some situations, unused space may comprise a significant portion of a realm file. Realm's default behavior is to automatically compact a realm file to prevent it from growing too large. You can use manual compaction strategies when automatic compaction is not sufficient for your use case or you're using a version of the SDK that doesn't have automatic compaction.

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:

  • Pinning transactions

  • Enhebrado

  • Dispatch Queues

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:

  • Thread A: Read some data from a realm, and then block the thread on a long-running operation.

  • Hilo B: Guarda datos en otro hilo.

  • Hilo A: La versión en el hilo de lectura no se actualiza. Realm debe mantener versiones intermedias de los datos, aumentando el tamaño del archivo con cada escritura.

To avoid this issue, call invalidate() on the realm. This tells the realm that you no longer need the objects you've read so far. This frees realm from tracking intermediate versions of those objects. The next time you access it, realm will have the latest version of the objects.

You can also use these two methods to compact your Realm:

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.

New in version 10.35.0.

The SDK automatically compacts Realm files in the background by continuously reallocating data within the file and removing unused file space. Automatic compaction is sufficient for minimizing the Realm file size for most applications.

Automatic compaction begins when the size of unused space in the file is more than twice the size of user data in the file. Automatic compaction only takes place when the file is not being accessed.

Manual compaction can be used for applications that require stricter management of file size or that use an older version of the SDK that does not support automatic compaction.

Realm manual compaction works by:

  1. Reading the entire contents of the realm file

  2. Writing the contents to a new file at a different location

  3. Replacing the original file

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

Use shouldCompactOnLaunch() (Swift) or shouldCompactOnLaunch (Objective-C) on a realm's configuration object to compact a realm. Specify conditions to execute this method, such as:

  • The size of the file on disk

  • La cantidad de espacio libre que contiene el archivo

For more information about the conditions to execute in the method, see: Tips for Using Manual Compaction.

Importante

Compacting may not occur

Compacting cannot occur while a realm is being accessed, regardless of any configuration settings.

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
}

When you use the Swift async/await syntax to open a realm asynchronously, you can compact a realm in the background.

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
}
}

Starting with Realm Swift SDK Versions 10.15.0 and 10.16.0, many of the Realm APIs support the Swift async/await syntax. Projects must meet these requirements:

Versión del SDK de Swift
Swift Version Requirement
Supported OS

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.

You can save a compacted (and optionally encrypted) copy of a realm to another file location with the Realm.writeCopy(toFile:encryptionKey:) method. The destination file cannot already exist.

Importante

Avoid calling this method within a write transaction. If called within a write transaction, this method copies the absolute latest data. This includes any uncommitted changes you made in the transaction before this method call.

Compacting a realm can be an expensive operation that can block the UI thread. Your application should not compact every time you open a realm. Instead, try to optimize compacting so your application does it just often enough to prevent the file size from growing too large. If your application runs in a resource-constrained environment, you may want to compact when you reach a certain file size or when the file size negatively impacts performance.

These recommendations can help you optimize manual compaction for your application:

  • 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 10 MB, puede establecer el tamaño máximo de archivo en 20 MB o 40 MB, según el uso previsto y las limitaciones del dispositivo.

  • As a starting point, compact realms when more than 50% of the realm file size is no longer in use. Divide the currently used bytes by the total file size to determine the percentage of space that is currently used. Then, check for that to be less than 50%. This means that greater than 50% of your realm file size is unused space, and it is a good time to compact. After experimentation, you may find a different percentage works best for your application.

Estos cálculos pueden tener el siguiente aspecto en su función de retorno 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

Experiment with conditions to find the right balance of how often to compact realm files in your application.

A large realm file can impact the performance and reliability of your app. Any single realm file cannot be larger than the amount of memory your application would be allowed to map in iOS. This limit depends on the device and on how fragmented the memory space is at that point in time.

If you need to store more data, map it over multiple realm files.

  • Realm's architecture enables threading-related benefits, but can result in file size growth.

  • Automatic compaction manages file size growth when the file is not being accessed.

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

  • Compacting cannot occur if another process is accessing the realm.

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

Volver

Bundle a Realm

En esta página