Оптимизировать потребление памяти, когда постепенно пишите в файл

StackOverflow https://stackoverflow.com/questions/3462428

Вопрос

Я делал некоторые тесты, и одно из моих потребностей - читать данные из разных файлов XML и стеките ее вместе в одном файле. Хотя мне удалось осуществить это, потребление памяти, похоже, довольно большая для задачи, симулятор iPhone даже не поднял предупреждение о памяти, но я не думаю, что настоящий iPhone будет терпеть это (у меня нет Устройство, чтобы попробовать это здесь, поэтому я в основном предпочитаю, что из того, что я прочитал).
(Основная часть) кода похожа:

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];
    }

Использование команды «Building и Analyze» дает мне никакой утечки или что-то еще, и код не поднимает предупреждения при строительстве, но все же, потребление памяти идет где-то от 50 до 70 МБ (просто учитывая живые байты, в целом это почти удваивает).
Идея, очевидно, не читает в 100 раз один и тот же файл, но в качестве тестовых данных его более чем хватает, поскольку код должен просто прочитать содержимое из файлов XML и отправить их в файл в порядке их получения.

Есть ли способ заставить выпуск некоторых временных объектов до выделения новых, могу ли я попытаться повторно использовать некоторые переменные, любые идеи, которые помогут мне сохранить это под контролем, действительно приветствуются.

Редактировать - Просто чтобы сделать вещи немного более интереснее: было бы лучше держать одного парсера, чтобы прочитать и писать, и тем самым было бы придерживаться gdataxml или, если необходим изменение, чтобы использовать KissXML, Tinixml или libxml - dom, который все, кажется, сосет немного больше памяти, как сказал здесь, Так что, если бы был способ обеспечить выпуск памяти, это было бы лучшим.

Заранее спасибо :)

Это было полезно?

Решение

На самом деле, это было довольно простое решение.

Все, что мне нужно было сделать, это создать резервную копию авторелеизулов и слить его в конце цикла.
Так:

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

Это вынужденное выпустить объекты, помеченные как авторелез, потрясенные внутри, которые были просто выпущены после окончания, как ожидалось, не мешая во всем остальном, поэтому никакие объекты не были освобождены до того, как они должны были.
Расход памяти снизился из склеенного 60 ~ 80 МБ к чему-то вроде 1,6 МБ во время цикла и возвращаясь к тому же 600 КБ после него (это было фиктивное приложение, которое сделало только это).

Я все равно оставлю этот вопрос на некоторое время, если кто-то имеет лучшую идею, но на данный момент, кажется, это будет так :)

Другие советы

Да, вы «удвоили» это, читая все это в Nsdata, а затем разбирая в DOM в GdataxMLDocument. Если вы ожидаете пройти много данных XML, как это, зацикливаете несколько файлов и т. Д., Тогда вы должны рассмотреть вместо этого разбор на основе SAX, и потоковую его прямо из файла, а не предварительно загрузить его в NSDATA. Таким образом, вам не придется «освободить временные объекты», потому что вы только извлекаете необходимую информацию, поскольку она анализируется.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top