Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> принудительная очистка памяти, принудительная очистка памяти: как? 
:(
    Опции темы
kulibinka
Дата 7.2.2007, 07:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 191
Регистрация: 20.11.2006

Репутация: 2
Всего: 4



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

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

и все равно, даже при таком подходе питон медленно но уверенно забирает себе все больше и больше памяти, и потому под конец работы весь файл подкачки все равно оказывается забитым и скрипт приходится выключать и запускать наново (хорошо что результаты обработанной части текстов сохраняются, и потому через несколько запусков скрипта я рано или поздно довожу скрипт до победного конца).

но хотелось бы знать: как заставить питон освободить всю ненужную мне память (кроме тех переменных, которые я ему скажу)?

попытки найти хоть что-то о принудительной очистке памяти в питоне, натыкался только на фразы типа "Python never returning memory to the operating system". Т.е. расслабся, используй xrange, купляй оперативки, увеличивай файл подкачки и жди нового питона...

все действительно так мрачно, или же есть решение этой проблемы?
PM MAIL   Вверх
Daevaorn
Дата 7.2.2007, 08:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 9
Всего: 70



PM MAIL WWW   Вверх
J2A
Дата 7.2.2007, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 17.11.2005
Где: Омск

Репутация: 16
Всего: 18



Возможно, есть вариант пересмотреть алгоритм обработки. Нужно ли, чтобы весь объем текст был в памяти? Если это последовательная обработка, стоит использовать итераторы/генераторы. Возможно, сериализация тоже будет вариантом - zodb/shelve? Если точнее опишешь что именно ты делаешь с текстами и как, то будет проще что-то советовать.
--------------------
Be easy, stay cool
PM MAIL WWW Jabber   Вверх
kulibinka
Дата 7.2.2007, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 191
Регистрация: 20.11.2006

Репутация: 2
Всего: 4



Написал пример кода, в котором я ну совершенно не понимаю куда уходит память:

Код

# -*- coding: windows-1251 -*-

from modules import *


def obj_from_file (f_name):
    """достает обьект питоновский из файла"""
    f = open(f_name, 'rb')
    return marshal.load(f)

def obj_to_file (obj, f_name):
    """заганяет обьект питоновский в файл"""
    f = open(f_name, 'wb')
    marshal.dump(obj, f)
    f.close()

def test_ute4ka(col_experementov = 100):
    """моделирую ситуацию, в которой должна быть утечка!"""    
    test_file = '1000'

    stroki = obj_from_file(test_file)
    print "v kazhdom cikle obrabativaetsja %d strok"%len(stroki)
    
    print 'start %d experementov' % col_experementov

#    а тут главный цикл
    for i in range (col_experementov):
        t_start = time.time()
        curent_info = []
        for s in stroki:
            stroka = Get_norms_from_text(s)
            curent_info.append(stroka)
        full_time = time.time() - t_start
        print i, full_time

    f = open('stat_info.csv', 'w')
    f.write("\n".join(exp_values))
    f.close()
    print "\nEND"

test_ute4ka(100)


И информация по коду и статистике:

Цитата

берем файлик (в которых замаршелены 100 фраз после обработки другой программой через obj_to_file), достаем из него фразы и колбасим все эти строки нужное количество раз ф-ей Get_norms_from_text (сюда не выкладываю, така как это часть большущего модуля, но суть в том что она возвращает список из нормированных слов фразы)

насколько я понимаю, каждый цикл не должен увеличивать память (ведь ничего нового не появляется)

а статистика показывает, что до запуска теста файл подкачки был 328 метра, перед началом цикла он дошел до 373, и потом каждый проход цикла уверенно забирал еще около метра (в конце работы файл подкачки за 100 шагов стал размером 505 метров, за 200 шагов - 630 метров)


Добавлено @ 18:08 
максимально упростил пример, утечка остается

Код

# -*- coding: windows-1251 -*-

from modules import *

def test_ute4ka(col_experementov = 100):
    """моделирую ситуацию, в которой должна быть утечка!"""    
    stroki = ['мама мыла раму, так как мама очень любила чистоту' for i in range(100)]
    
    print 'start %d experementov' % col_experementov

#    а тут главный цикл
    for i in range (col_experementov):
        t_start = time.time()
        curent_info = []
        for s in stroki:
            stroka = Get_norms_from_text(s)
            curent_info.append(stroka)
        full_time = time.time() - t_start
        print i, full_time


test_ute4ka(100)


Это сообщение отредактировал(а) kulibinka - 7.2.2007, 18:01
PM MAIL   Вверх
kulibinka
Дата 7.2.2007, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 191
Регистрация: 20.11.2006

Репутация: 2
Всего: 4



новая информация: я знаю что течет мой модуль modules
потому что если вынести ф-ю Get_norms_from_text в код теста и ничего больше не использовать, то все отлично.
если же использовать ее подключая модуль modules, то начинается утечка.
узнать бы что именно в этом модуле течет...

Добавлено @ 19:06 
бррр
как так - подключаю модуль, который сам по себе работает отлично, и начинается утечка.
а не подключаю - не начинается...
причем нигде в модулях не используется ничего похожего (связанного) на те ф-и которые в этом тестовом коде используются... ну откуда она может взяться?
PM MAIL   Вверх
J2A
Дата 7.2.2007, 19:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 17.11.2005
Где: Омск

Репутация: 16
Всего: 18



На вскидку:

1) Используй xrange вместо range.Почему: раз и два.
2) Зачем тебе в памяти хранить строки, если ты только и делаешь, что цикл по ним? Сделай итератор, который будешь перезапускать в каждой итерации главного цикла. Очень сильно сэкономишь память.
3) Не импортируй все из модуля. Почему.
4) Вообще выкинь цикл по строкам - используй list comprehensive:
вместо
Код

curent_info = []
for s in stroki:
            stroka = Get_norms_from_text(s)
            curent_info.append(stroka)

делай так:
Код

current_info = [Get_norms_from_text(s) for s in stroki]

Почему.

В общем, be Pythonic.

P.S. И переменные нормально называй. experiments_number например

Это сообщение отредактировал(а) J2A - 7.2.2007, 19:21
--------------------
Be easy, stay cool
PM MAIL WWW Jabber   Вверх
kulibinka
Дата 7.2.2007, 19:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 191
Регистрация: 20.11.2006

Репутация: 2
Всего: 4



Спасибо за советы.
Но без применения 1, 2 и 4 код отлично работает, так как если заменить ф-ю Get_norms_from_text то никакой утечки нету.
А ответ где-то видимо около 3, я там как разу кручусь - пытаюсь импортировать только используемые ф-и и посмотреть на утечку.

Добавлено @ 19:19 
а с пунктом 4 я категорически несогласен, так как предложенный Вами варианта на порядок тугодумнее. Да, он питоник и на него приятно смотреть, но работает он туго.
PM MAIL   Вверх
J2A
Дата 7.2.2007, 19:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 17.11.2005
Где: Омск

Репутация: 16
Всего: 18



На порядок тугодумнее? Факты-с в студию! Пока не увижу - не поверю.
--------------------
Be easy, stay cool
PM MAIL WWW Jabber   Вверх
kulibinka
Дата 7.2.2007, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 191
Регистрация: 20.11.2006

Репутация: 2
Всего: 4



попытался подобрать факты - не смог smile
помню что еще в самом начале обработки больших текстовых массивов информации питоник-вариант обработки списков у меня практически всегда забивал весь файл подкачки и скрипт вылетал с ошибкой мемориеррор, но при этом отлично продолжал работать если я обрабатывал списки тупо в лоб.
я тогда решил что питоник не предусмотрен для больших-пребольших списков, и с того момента пишу все только в лоб.
но сейчас попытки вызвать ту же ошибку

Цитата

# -*- coding: windows-1251 -*-

import time

def another_function (text):
    rezult = []
    words = text.split(' ')
    for i in range(100):
  for w in words:
    rezult.append(w.lower())
    rezult.append(w.upper())
    return rezult

def func1 (stroki):
    return [another_function(s) for s in stroki]

def func2 (stroki):
    rezult = []
    for s in stroki:
  rezult.append(another_function(s))
    return rezult

def func22 (stroki):
    rezult = []
    for s in stroki:
  t = another_function(s)
  rezult.append(t)
    return rezult

def func3 (stroki):
    return map(another_function, stroki)
    


def test_function(test_function, col_experementov = 1000, message=''):
    """тест ф-й"""
    print message, 
    t1=time.time()
    stroki = ['мама мыла раму так как мама очень любила чистоту' for i in range(col_experementov)]

#    а тут главный цикл
    rezult = test_function(stroki)

    print time.time()-t1
    return rezult


test_function(func1, 10000, 'pythonic')
test_function(func2, 10000, 'v lob')
test_function(func22, 10000, 'v lob 2')
test_function(func3, 10000, 'map')


ни к чему не привели - и по времени, и по использованию файла подкачки все ф-ии работают приблизительно одинаково (за 75-80 секунд).

хотя работать в питоник-стайл оно конечно красивше smile

Добавлено @ 20:48 
кстати, я поборол утечку smile

оказывается у меня modules использовал psyco, и после убивания psyco утечка памяти прошла сама собой.

наверное это потому, что psyco не дружит с си, а модуль, который использует ф-я Get_norms_from_text, написан как раз на си.

всем огромное спасибо за советы!
PM MAIL   Вверх
J2A
Дата 8.2.2007, 06:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 17.11.2005
Где: Омск

Репутация: 16
Всего: 18



Немного гиперболизируя, ты тестируешь феррарри и трактор  по скорости. Цепляешь к обоим прицеп на полторы тонны. По скорости 10 км/ч с прицепом по грунтовке, делаешь вывод, что максимальные скорости одинаковы, только феррарри чуть покрасивше.

Код

$ python -m timeit 'res = []' 'for i in xrange(10000): res.append(i)'
100 loops, best of 3: 3.77 msec per loop
$ python -m timeit 'res = [i for i in xrange(10000)]'
1000 loops, best of 3: 1.68 msec per loop

--------------------
Be easy, stay cool
PM MAIL WWW Jabber   Вверх
kulibinka
Дата 8.2.2007, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 191
Регистрация: 20.11.2006

Репутация: 2
Всего: 4



абсолютно правильная аналогия
только я без прицепов от двух тонн не ездяю.

А вообще я больше люблю трактора...

Потому что в Ваше красивое ферари я вообще ничего своего вкрутить не смогу - оно цельное, без нужных мне дырок для болтов, и предназначено использоваться только как есть.

Ну а трактор это хорошо - делай дырок сколько угодно, прикручивай туда кучу прибамбасов, грузи его как угодно, и он при всем при этом останется старым добрым рабочим трактором.

У меня например на все тракторы установлен джпс-навигатор, потому что без него совершенно непонятно работают ли скрипты, срок работы которых несколько часов, или же просто стоят...

А ферари там тихо мирно сопит... работает, не работает - совершенно непонятно... и через 10 минут черный экран начинает нервировать... движение есть, а прогресса нет... ну что с него возьмешь - феррари оно и в африке феррари smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Python: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0875 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.