Menu Docs
Página inicial do Docs
/ /
Atlas Device SDKs
/ /

Reduzir o tamanho do Arquivo de Realm - Swift SDK

Nesta página

  • Visão geral
  • Tamanho do arquivo de Realm
  • Evitar a fixação de transações
  • Segmentação
  • Filas de despacho
  • Compactação automática
  • Compactação manual
  • Compacte um Realm de modo assíncrono
  • Fazer uma cópia compactada
  • Dicas para usar compactação manual
  • Resumo

O tamanho de um arquivo de Realm é sempre maior que o tamanho total dos objetos armazenados dentro dele. Essa arquitetura permite alguns dos excelentes benefícios de desempenho, simultaneidade e segurança do realm.

O Realm escreve novos dados em espaços livres já monitorados dentro de um arquivo. Em certos casos, o espaço não utilizado pode incluir uma parte significativa de um arquivo de Realm. Por padrão, o Realm compacta automaticamente arquivos de realm para impedir que eles se tornem excessivamente grandes. Você pode usar técnicas de compactação manual se a automática for insuficiente para o seu caso de uso, ou se estiver usando uma versão do SDK que não suporte compactação automática.

Geralmente, um arquivo realm ocupa menos espaço no disco do que um banco de dados SQLite comparável. O crescimento de arquivo inesperado pode estar relacionado aos Atlas App Services referindo-se a dados desatualizados. Esses fatores podem afetar o tamanho do arquivo:

  • Transações de Pins

  • Segmentação

  • Filas de despacho

Quando você considera reduzir o tamanho do arquivo por meio da compactação, há algumas coisas a ter em mente:

  • A compactação pode ser uma operação que consome muitos recursos

  • A compactação pode bloquear a thread da UI

Because of these factors, you probably don't want to compact a realm every time you open it, but instead want to consider when to compact a realm. This varies based on your application's platform and usage patterns. When deciding when to compact, consider iOS file size limitations.

O realm vincula o tempo de vida das transações de leitura ao tempo de vida da memória das instâncias do realm. Evite "fixar" transações antigas do Realm. Use realms de atualização automática e encapsular o uso de APIs de Realm de threads em segundo plano em pools de liberação automática explícitos.

O Realm atualiza a versão dos seus dados que acessa no início de uma iteração de loop de execução. Embora isso ofereça uma visão consistente dos seus dados, isso tem implicações no tamanho do arquivo.

Imagine este cenário:

  • Thread A: Leia alguns dados de um realm e, em seguida, bloqueie o thread em uma operação de longa execução.

  • Thread B: Grava dados em outro thread.

  • Thread A: A versão no tópico de leitura não está atualizada. O Realm precisa conter versões intermediárias dos dados, aumentando o tamanho do arquivo a cada gravação.

Para evitar esse problema, chame o método invalidate() no realm. Isso informa ao Realm que você não precisa mais dos objetos de Realm que leu até agora. Isso libera o Realm de rastrear versões intermediárias desses objetos de Realm. Da próxima vez que você acessá-lo, o Realm terá a versão mais recente dos objetos de Realm.

Você também pode usar esses dois métodos para compactar seu Realm:

Dica

Veja também:

Ao acessar o domínio usando o Grand Central Dispatch, você pode ver um crescimento de arquivo semelhante. O pool de liberação automática de uma fila de despacho pode não se esgotar imediatamente após a execução do código. O domínio não pode reutilizar versões intermediárias dos dados até que o pool de despacho desaloque o Objeto de Realm. Use um pool de liberação automática explícito ao acessar o domínio a partir de uma fila de despacho.

Novidades na versão 10.35.0.

O SDK compacta automaticamente os arquivos do Realm em segundo plano, realocando continuamente os dados no arquivo e removendo o espaço de arquivo não utilizado. A compactação automática é suficiente para minimizar o tamanho do arquivo Realm para a maioria dos aplicativos.

A compactação automática é acionada quando o tamanho do espaço não utilizado do arquivo excede o dobro do tamanho dos dados do usuário contidos no arquivo. A compactação automática só ocorre quando o arquivo não está sendo acessado.

A compactação manual pode ser usada para aplicativos que exigem um gerenciamento mais rigoroso do tamanho do arquivo ou que usam uma versão mais antiga do SDK que não permite a compactação automática.

A compactação manual do realm funciona por:

  1. Lendo todo o conteúdo do arquivo de área

  2. Escrevendo o conteúdo em um novo arquivo em um local diferente

  3. Substituindo o arquivo original

Se o arquivo contiver muitos dados, pode ser uma operação cara.

Use shouldCompactOnLaunch() (Swift) ou shouldCompactOnLaunch (Objective-C) em um objeto de configuração do realm para compactar um realm. Especifique as condições para executar este método, como:

  • O tamanho do arquivo no disco

  • Quanto espaço livre o arquivo contém

Para obter mais informações sobre as condições a serem executadas no método, consulte: Dicas para usar a compactação manual.

Importante

A compactação pode não ocorrer

A compactação não pode ocorrer enquanto um realm estiver sendo acessado, independentemente de quaisquer definições de configuração.

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
}

Ao usar a sintaxe async/await do Swift para abrir um realm de forma assíncrona, você pode compactar um realm no 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
}
}

A partir das versões 10.15.0 e 10.16.0 do SDK do Realm Swift, muitas das APIs do Realm suportam a sintaxe async/await do Swift. Os projetos devem atender a estes requisitos:

Versão do Swift SDK
Requisito de versão do Swift
Sistema operacional compatível
10.25.0
Swift 5.6
iOS 13.x
10.15.0 ou 10.16.0
Swift 5.5
iOS 15.x

Se a sua aplicação acessar Realm em um contexto do async/await, marque o código com @MainActor para evitar falhas relacionadas a threading.

Você pode salvar uma cópia compactada (e, opcionalmente, criptografada) de um domínio para outro local de arquivo com o método Realm.writeCopy(toFile:encryptionKey:) . O arquivo de destino já não pode existir.

Importante

Evite ligar para esse método em uma transação de gravação. Se for chamado em uma transação de gravação, esse método copiará os dados absolutamente mais recentes. Isso inclui todas as alterações não confirmadas que você fez na transação antes dessa chamada de método.

A compactação de um realm pode ser uma operação cara que pode bloquear o thread da UI. Seu aplicativo não deve ser compactado toda vez que você abrir um realm. Em vez disso, tente otimizar a compactação para que seu aplicativo faça isso com frequência suficiente para evitar que o tamanho do arquivo cresça muito. Se o seu aplicativo for executado em um ambiente com restrição de recursos, você pode querer compactar quando chegar a um determinado tamanho de arquivo ou quando o tamanho do arquivo afetar negativamente o desempenho.

Essas recomendações podem ajudá-lo a otimizar a compactação manual de seu aplicativo:

  • Defina o tamanho máximo do arquivo como um múltiplo do tamanho médio do estado do Realm. Se o estado médio do Realm for de 10MB, defina o tamanho máximo do arquivo Realm entre 20MB e 40MB, considerando o uso previsto e as restrições do dispositivo.

  • Como ponto de partida, os domínios compactos quando mais de 50% do tamanho do arquivo de área não estão mais em uso. Divida os bytes atualmente usados pelo tamanho total do arquivo para determinar a porcentagem de espaço que está sendo usada atualmente. Em seguida, verifique se é inferior a 50%. Isso significa que mais de 50% do tamanho do arquivo do seu realm é espaço não utilizado e é um bom momento para compactar. Após a experimentação, você pode descobrir que uma porcentagem diferente funciona melhor para seu aplicativo.

Esses cálculos podem ter a seguinte aparência em seu chamada de resposta 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 as condições para encontrar o equilíbrio certo entre a frequência de compactação dos arquivos de realm em seu aplicativo.

Um arquivo de domínio grande pode afetar o desempenho e a confiabilidade do seu aplicativo. Qualquer arquivo de domínio único não pode ser maior que a quantidade de memória que seu aplicativo poderá mapear no iOS. Esse limite aponta do dispositivo e da fragmentação do espaço de memória naquele momento.

Se precisar armazenar mais dados, mapeie-os em vários arquivos de região.

  • A arquitetura do Realm permite benefícios relacionados ao threading, mas pode resultar no aumento do tamanho do arquivo.

  • A compactação automática gerencia o crescimento do tamanho do arquivo quando ele não está sendo acessado.

  • Estratégias manuais de compactação como shouldCompactOnLaunch() podem ser usadas quando a compactação automática não atende às necessidades do aplicativo.

  • A compactação não poderá ocorrer se outro processo estiver acessando o realm.

  • Você pode compactar um domínio em segundo plano ao usar a sintaxe async/await.

Voltar

Agrupar um realm

Próximo

Criptografar um Realm