i876 - Memória

mcardoso
Posts: 3
Joined: 2008-10-09

Olá,

Desenvolvo aplicativos corporativos em j2me para dispositivos móveis. Durante a realizaçãode testes de compatibilidade com o aparelho i876, no processo de extração dos dados recebidos do servidor, o sistema lançou uma exceção de falta de memória (java.lang.OutOfMemoryError). Analisando a especificação, identifiquei que este aparelho possuí 25MB de memória heap, que é bastante superior a outros dispositivos que são compatíveis com os softwares que desenvolvo.
Minha questão, então, é: Alguém sabe se este celular (i876) possuí algum problema de gerenciamento de memória ou algum outro bug que possa ocasionar tal erro.

Att,

Marcelo Valim Cardoso



Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
jfrincon
Posts: 289
Joined: 2006-12-01
Memória no i876

Olá Marcelo,

Tudo bem?

Eu sei que existe uma certa particularidade no uso do FileConnection API no i876 que é manifestado quando escreve muitos files muito pequenos. Mais não que estejam gerando esse erro.

Mais a pergunta é a seguinte -- quantos dados você vem recebendo do servidor, e que você está fazendo com eles? Os esta guardando numa variável? Esta escrevendo o InputStream ao RMS? Vai leiendo o InputStream para determinar alguma processamento?

Ajudaria um pouco saber um pouco mais do código. O outro que é importante saber é, quando vai ao menu Java e escolhe "Sobre", na tela que indica memória, quais valores você pode ver?

Um abraço,

Juan Felipe



mcardoso
Posts: 3
Joined: 2008-10-09
Olá, Juan. Primeiramente,

Olá, Juan.

Primeiramente, agradeço sua resposta e consideração em me auxiliar neste problema.

Neste caso, estou recebendo do servidor em torno de 1MB de informações de texto quebradas em blocos de 4KB. Esses blocos são armazenados em rms com a finalidade de serem tratados ao término do recebimento dos mesmos. Uma vez concluída a recepção, os dados são lidos do rms e discriminados em entidades (produtos, clientes, etc..)

Esse processo acontece da seguinte maneira: leio os dados do rms (cada caracter eh lido individualmente para que seja identificado o protocolo de transmissão); uma vez identificado um registro da entidade, esse é escrito em um DataOutputStream e posteriormente transformado em um array de bytes para ser salvo no rms referente a entidade em questão.

Cada entidade é armazenada em um rms diferente, sendo que possuo aproximadamente 25 entidades distintas.

No teste realizado, a entidade com o maior número de registros possuía 3 mil produtos, 9 mil índices, 3 mil preços, e as outras números inferiores.

Quanto a sua outra pergunta, o espaço de dados disponível para o Java é de 7980KB e a memória heap é de 6144KB. Na especificação do aparelho, está descrito que a segunda é de 25MB.. Estaria reservado à VM aproximadamente 18MB?
Mesmo tendo essa quantidade de memória disponível, acredito que o sistema funcionaria com sucesso.

Espero que tenha conseguido explicar basicamente o sistema..

Att,

Marcelo Valim Cardoso



jfrincon
Posts: 289
Joined: 2006-12-01
RE:Memória no i876

Olá Marcelo,

Ja vou entendindo. Eu acredito que esta achando um erro nas nossas especificações, não no aparelho.

O Java ME Heap representa o espaço disponível para a execução do aplicativo -- basicamente, a memória dedicada pelos objetos que são criados na execução, gerenciamento dos threads que vão rodando, etc. Mais estou vindo e acredito que o dado na página com a especificação é errado. O valor correto é aquele que você vei, 6144k para a execução. Esses 25MB vieram de um email que eu recebi dum técnico da Motorola, mais olhando com mais detalhe, vejo que com certeza não tem esses valores.

O armazenamento de dados acontece no "Data Space". O data space é compartilhados por todos os outros aplicativos que vão armazenando dados no aparelho, além dos tons e wallpapers, MP3 e vídeos, JAR e JADs que tenha residentes no aparelho. Ele representa 12MB da memória do aparelho.

Eu já atualizei as especificações do i876 para que estejam certas.

Desculpe o erro.

Mais isso não responde a por que acontece esse erro de memória.

Eu acredito que tem que ver com o método que vem usando para os escrever no RMS.
Os aparelhos iDEN tem um limite físico de 2048 registros no RMS. Cada ringtone, wallpaper, ou RecordStore individual criado por um aplicativo reduz esse número.
Se você esta criando um novo recorde com cada um de esses pacotes de 4kb do total de 1MB, vai terminar lotando a quantidade de registros (4kb * 2048 = 1MB). Não sei se você esta fazendo isso, ou se vem encaminhando cada bloco de 4kb ao mesmo RecordStore. A pergunta é: quantas chamadas a

recordStore = RecordStore.openRecordStore(rsName,true,
(byte)RecordStore.AUTHMODE_ANY, true)

vem fazendo o aplicativo? Uma chamada somente? Ou uma por cada bloco de 4kb?

No momento de escrever o dado re-interpretado no RMS, esta fazendo adicionando ao RMS correspondente à entidade? ou criando um novo RMS que vai com um índice ou referencia?

A outra possibilidade que eu recomendaria -- tentou gravar os registros recebidos da rede num File, e somente depois de isso ir criando o RMS quando tem os dados completos?

Um abraço,

Juan Felipe



mcardoso
Posts: 3
Joined: 2008-10-09
Ola Juan, Não consegui

Ola Juan,

Não consegui entender exatamente que limite é esse de 2048 registros.. seriam 2048KB? ou 2048 registros por RMS?

vou fazer um exemplo aqui para você entender +- como funciona o processo:

1) Receber os dados do servidor:
Exemplo: *Produtos|Bola^R$10,00|Boneca^R$15,00|Carrinho^R$5,00*Clientes|João^Brasil|André^Argentina|Pedro^Canadá

(Esses dados são quebrados a cada 4KB e salvos em um único RMS, ou seja, cada registro do RMS terá 4KB)

2) Extrair os dados:

No exemplo, temos duas entidades: produtos e clientes!
Após a extração dos dados, ficaremos com apenas 2 RMSs, já que após o processo de extração o RMS que continha os dados recebidos do servidor é apagado:

RMS Produtos:
Bola R$10,00
Boneca R$15,00
Carrinho R$5,00

RMS Clientes:
João Brasil
André Argentina
Pedro Canadá

Acredito que agora tenha ficado um pouco mais claro com o exemplo acima.

Como eu tinha comentado antes, os dados são extraídos em um DataOutputStream e posteriormente transoformados em um array de bytes para ser salvos no RMS.. Não tentei salvar em um File e posteriormente salvar.. existe alguma vantagem significativa em realizar este processo?

Att,
Marcelo Valim Cardoso



jfrincon
Posts: 289
Joined: 2006-12-01
RMS e número de registros

Ola Marcelo,

Bom dia.

Posso aclarar sobre o RMS.

Cada vez que você chama

recordStore = RecordStore.openRecordStore(rsName,true,
(byte)RecordStore.AUTHMODE_ANY, true)

esta criando um novo record store. Pode fazer esse chamado um máximo teórico de 2048 vezes para criar novos RecordStores.

Se o seu processo de salvar os dados é algo como

recordStore = RecordStore.openRecordStore(rsName,true, (byte)RecordStore.AUTHMODE_ANY, true);
for (int i=0; i < numRegistros; i++)
{
   recordStore.addRecord(...);
}

esse limite não vai te afeitar.

Como eu tinha comentado antes, os dados são extraídos em um DataOutputStream e posteriormente transoformados em um array de bytes para ser salvos no RMS.. Não tentei salvar em um File e posteriormente salvar.. existe alguma vantagem significativa em realizar este processo?

Existe -- mais que tudo em velocidade de acesso. Cada vez que chama recordStore.addRecord() o aparelho vai gerando um indice para o record para ele poder ser procurado depois. Quando escreve ao FileOutputStream, somente esta encaminhando os dados direitinho a um bloco de memória reservado. Pode ser que lhe dei uma melhor resposta.

Para saber mais eu precisaria vero o seu código.