Pergunta

Eu tenho feito alguns testes e uma das minhas necessidades é ler dados de diferentes arquivos XML e empilhá -los em um único arquivo. Enquanto eu consegui conseguir isso, o consumo de memória parece ser bastante grande para a tarefa, o simulador do iPhone nem levantou o aviso de memória, mas não acho que o iPhone real toleraria isso (eu não tenho Um dispositivo para experimentá -lo aqui, por isso estou especulando principalmente pelo que li).
A (parte principal do) código é como:

Boolean success = [fileManager createFileAtPath:documentsPath contents:nil attributes:nil];
[fileManager release];

if (success) {
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:documentsPath];
    for (int i = 0; i < 100; i++) {

        NSString *path = [[NSBundle mainBundle] pathForResource:@"mensagem_de_arquivo" 
                                                         ofType:@"xml"];
        NSData *data = [NSData dataWithContentsOfFile:path];
        GDataXMLDocument *xml = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil];
        NSArray *tokens = [xml nodesForXPath:@"//message/data" error:nil];
        if (tokens.count > 0) {
            GDataXMLElement *token = (GDataXMLElement *)[tokens objectAtIndex:0];
            [fileHandle writeData:[[token stringValue] dataUsingEncoding:NSASCIIStringEncoding]];
        }
        [xml release];
    }

Usando o comando "Build and Analyze" não me dá vazamento nem nada, e o código não levanta avisos ao criar, mas ainda assim, o consumo de memória fica entre 50 e 70 MB (apenas considerando bytes ao vivo, no geral, quase dobra).
A idéia obviamente não é ler 100 vezes o mesmo arquivo, mas como os dados de teste é mais do que basta, pois o código precisa apenas ler o conteúdo dos arquivos XML e enviá -los para um arquivo no pedido que eles são recebidos.

Existe alguma maneira de forçar a liberação de alguns objetos temporários antes que os novos sejam alocados, posso tentar reutilizar algumas variáveis, quaisquer idéias que me ajudem a manter isso sob controle são realmente bem -vindas.

Editar - Apenas para tornar as coisas um pouco mais interessantes: seria melhor manter um único analisador para ler e escrever, e com isso o melhor seria ficar com gdataxml ou, se uma alteração fosse necessária, para usar o Kissxml, Tinyxml ou libxml - dom, que parece sugar um pouco mais de memória, como disse aqui, então, se houvesse uma maneira de aplicar o lançamento da memória, seria o melhor.

Desde já, obrigado :)

Foi útil?

Solução

Na verdade, foi uma resolução bastante simples.

Tudo o que eu precisava fazer era instanciar um autorleasepool e drená -lo no final do loop.
Assim:

for (int i = 0; i < 100; i++) {
    NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init];
    //... do everything I've done before...
    [pool drain];
}

Isso forçou a liberar objetos marcados como autorlease instanciados dentro do para, que estavam sendo lançados após o final, como era esperado, sem interferir em todo o resto, para que nenhum objetivo fosse liberado antes de deveriam.
O consumo de memória caiu de 60 ~ 80 MB para algo como 1,6 MB durante o loop e voltando aos mesmos 600 KB depois (foi um aplicativo fictício que fez exatamente isso).

Ainda vou deixar essa pergunta em aberto por um tempo, caso alguém tenha uma ideia melhor, mas por enquanto parece que esse será o caminho :)

Outras dicas

Sim, você "dobrou" lendo tudo em um nsdata, depois analisando um DOM em gdataxmldocument. Se você espera passar por muitos dados XML como esse, loop em vários arquivos, etc., então você deve Considere a análise baseada em sax em vez, e transmitindo -o diretamente do arquivo, em vez de pré -carregá -lo em um NSDATA. Dessa forma, você não precisará "liberar objetos temporários" porque você estará extraindo apenas as informações necessárias, pois elas são analisadas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top