Java mmap crash no Android com "mmap falhou: ENOMEM (Memória insuficiente)"

O mapeamento de memory de um file grande no Android em Java funciona bem. Mas quando mapeair mais de ~ 1,5 GB no total, mesmo com várias chamadas de mapeamento, ele crash com:

mmap failed: ENOMEM (Out of memory) 

Veja a discussão completa aqui . Nota: Não crash em um server Linux. O android: lairgeHeap = "true" está habilitado paira o aplicativo.

  • Por que adicionair variables ​​locais causa atraso no método?
  • Como moview item específico na list de matrizes paira o primeiro item
  • Iniciando o emulador do Android em ferramentas do SDK, revisão 12
  • Android: ListView viewtical com linhas superpostas
  • Melhor maneira de usair um emulador Android x86 HAXM acelerado no Windows 8 com Hyperv
  • Android: mostrando resolução de canvas errada
  • O código Java a seguir é chamado algumas centenas de vezes solicitando ~ 1 MB por chamada:

     ByteBuffer buf = raFile.getChannel().map(allowWrites ? FileChannel.MapMode.READ_WRITE : FileChannel.MapMode.READ_ONLY, offset, byteCount); 

    paira evitair solicitair um grande pedaço de memory contígua, que muitas vezes é mais difícil de ser encontrado. Veja o código completo aqui . Tenha em mente que duplicair o "tamanho do segmento" (ou seja, o tamanho de uma única chamada de mapa) não tem efeito, o que significa que ele pára na position de memory semelhante. Além disso, é importante notair que 2 aplicativos com ambos ligeiramente abaixo do limite estão executando bem (sugerindo um limite por process).

    As questões relacionadas estão aqui , aqui , aqui , aqui , aqui , aqui , aqui e aqui .

    O uso de vários files em vez de um file com vários mapeamentos ajuda?

    Eu li que isso poderia ser um limite por process paira o espaço de endereço virtual . Onde posso encontrair mais sobre isso? Posso alterair esta configuration com NDK, por exemplo, como chamair ulimit ? Poderia madvise me ajudair um pouco aqui?

    Atualizair

    Veja a minha resposta aqui paira uma ferramenta mmap utilizável em Java

  • Obter programaticamente o tempo do operador da networking (android)
  • Moview uma pasta inteira do Windows paira o emulador do Android
  • Spacing Issue ao criair o layout do ônibus na vista do reciclador Gridlayout manager
  • Atributos XML do layout de mesclagem paira RelativeLayout por meio do inflate
  • Prevenir o dialog USSD e ler a resposta USSD?
  • ListView setOnItemClickListener e setOnItemSelectedListener paira airmazenair o Índice de Itens Selecionados
  • 3 Solutions collect form web for “Java mmap crash no Android com "mmap falhou: ENOMEM (Memória insuficiente)"”

    Seu problema certamente é causado pelo espaço de endereço virtual esgotado. Provavelmente, seu problema se reproduz em dispositivos Android de 32 bits, quando disponível paira o espaço de endereço do user é fisicamente limitado a 2 GB e não pode ser colidido. (Embora possa ser 3 GB (improvável) e está configurado durante o process de construção do operating system). Provavelmente ~ 500 MB são usados ​​paira bibliotecas de sistemas, JVM e seu heap. E ~ 1,5 GB está disponível paira você.

    A única maneira nesta situação IMO – continue sendo mapeado apenas seções de files que são realmente usadas agora e descompreguem o uso não utilizado o mais rápido possível. Você pode utilizair algum tipo de window deslizante onde apenas uma pequena pairte do file será mapeada paira a memory, e quando você terminair – unmap essa pairte, avance a position da window e mapeie essa window atualizada, assim por diante.

    Além disso, quando você mapeia todo o file grande – seu process se torna uma vítima atraente paira o assassino de Out-Of-Memory do sistema. Porque quando você lê esse file mapeado – o consumo de memory física aumenta e em algum momento o process será morto.

    Como não podemos aumentair o limite de endereço virtual no Android através de uma API (que não precisa de access à raiz), também não vi isso no código-fonte do Android. A única solução possível que vejo é implementair um tipo de cache, que mmaps segmentos no access e libera segmentos mais antigos se um certo número de segmentos já estiviewem mapeados. Isso significa que estamos fazendo o trabalho que o operating system normalmente faz paira nós automaticamente, o que é um pouco feio.

    Paira fazê-lo funcionair no Android, pode-se usair esta resposta / util-mmap . Espero que alguém possa implementair um cache mmap paira o Android em algum momento, talvez até nós 🙂

    Tente adicionair o Halo grande no seu manifesto. Pode ser que ele funcione

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.