Pregunta

He estado haciendo algunas pruebas, y una de mis necesidades es leer los datos de diferentes archivos XML y apilar juntos en un solo archivo. Mientras que he conseguido lograr esto, el consumo de memoria parece ser bastante grande para la tarea, el simulador de iPhone ni siquiera plantear la advertencia de memoria, pero no creo que el verdadero iPhone toleraría esto (no tengo un dispositivo para tratar aquí, así que estoy especulando que la mayoría de lo que he leído).
El (parte principal de la) código es 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];
    }

Uso de la "construir y analizar los" comandos me da ninguna fuga ni nada, y el código no plantea advertencias en la construcción, pero aún así, el consumo de memoria va a alguna parte entre 50 y 70 MB (solo considerando bytes en vivo, en general, casi se duplica ).
La idea, obviamente, no es leer 100 veces el mismo archivo, pero a medida que los datos de prueba que más basta, ya que el código tiene que leer simplemente el contenido de los archivos XML y enviarlos a un archivo en el orden en que se reciben.

¿Hay alguna manera de forzar la liberación de algunos objetos temporales antes de asignar nuevos, podría tratar de reutilizar algunas variables, todas las ideas que me ayudan a mantener esto bajo control son muy bienvenidos.

Editar - sólo para hacer las cosas un poco más interesante: que sería mejor mantener un único analizador de leer y escribir, y que lo mejor sería seguir con GDataXML o, si se necesitaba un cambio, utilizar KissXML, TinyXML o libxml - DOM, que todos parecen absorber un poco más de memoria, como dijo aquí , por lo que si había una manera de hacer cumplir la liberación de la memoria sería la mejor.

Gracias de antemano:)

¿Fue útil?

Solución

En realidad, era una solución muy simple.

Todo lo que tenía que hacer era crear una instancia de un AutoReleasePool y drenarlo al final del bucle.
De esta manera:

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

Esta obligado a liberar objetos marcados como autorelease instancia dentro de la para, que acaban de ser puesto en libertad después de su final, como era de esperar, sin interferir en todo lo demás, por lo que no hay objetos fueron puestos en libertad antes de lo que deberían.
El consumo de memoria se redujo de un ferina 60 ~ 80 MB a algo así como 1,6mb durante el bucle, y volviendo a la misma después de que 600kb (que era una aplicación ficticia que realiza justo esto).

Todavía va a dejar esta pregunta abierta por un tiempo, en caso de que alguien tiene una idea mejor, pero por ahora, parece que esta será la forma:)

Otros consejos

Sí, usted ha "duplicado" mediante la lectura de todo en un NSData, a continuación, analizar en un DOM en GDataXMLDocument. Si usted está esperando para pasar por un montón de datos XML como este, de enlace a través de múltiples archivos, etc., entonces debería tener en cuenta el análisis basado en lugar SAX, y el streaming directamente desde el archivo en lugar de precarga en un NSData. De esa manera, usted no tendrá que "liberar objetos temporales", ya que sólo estará extrayendo la información que necesita, como se analiza.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top