+ Ответить в теме
Показано с 1 по 3 из 3
  1. #1
    Аватар для Алексей322 Алексей322 На пути к лучшему Прохожий
    Сообщений
    65
    Поблагодарили 8 раз(а) в 6 сообщениях

    Утечка памяти в потоке с использованием SyncEx и Sync

    Доброго времени суток, форумчане.
    Наткнулся на проблему, при использовании синхронизации в потоке, а именно функций syncEx и sync происходит утечка памяти. Покопавшись в файлах ds, я нашел такую интересную строчку:
    PHP код:
    gui_threadSync($GLOBALS['THREAD_SELF'], 'TThread::__syncFull'igbinary_serialize($args)); 
    в которой идет обращение уже к функции Delphi. Собственно говоря, gui_threadSync работает некорректно, при маленьких задержках цикла в потоке. Вот пример утечки памяти:
    PHP код:
    function test()
    {
    while(
    1)
    syncEx("file_get_contents",array("Project.events"));
    }

    $th = new TThread();
    $th->onExecute 'test';
    $th->resume(); 
    А вот так все нормально:
    PHP код:
    function test()
    {
    while(
    1)
    file_get_contents("Project.events");
    }

    $th = new TThread();
    $th->onExecute 'test';
    $th->resume(); 
    Лезем в диспетчер задач и находим, что в примере 1 каждую секунду объем памяти увеличивается +~1 мб. С 20 потоков, программа рухнет через пару минут. В примере 2, все работает на ура.

    Собственно вопрос, братцы, есть ли какой то еще аналог syncEx и sync, для того что бы можно было получить доступ к окружению глобальных переменных в главной программе и синхронизации gui компонентов без утечки памяти? Мб есть какие то переписанные SE, где этот баг исправлен... Сгодится все.

    З.Ы. код приведен чисто для примера, никакого смысла он не несет.
    Последний раз редактировалось Алексей322; 18.09.2018 в 18:05.

  2. #2
    Аватар для PiEy PiEy Очень опасный тип PiEy Очень опасный тип PiEy Очень опасный тип Путешественник
    Сообщений
    430
    Поблагодарили 40 раз(а) в 40 сообщениях
    Чисто говоря, была такая проблема...
    Поток в потоке не завершается... Как то так, надо через какое то время его "ЕБАНУТЬ нхауй" а точнее перебать этот поток

  3. #3
    Аватар для Алексей322 Алексей322 На пути к лучшему Прохожий
    Сообщений
    65
    Поблагодарили 8 раз(а) в 6 сообщениях
    Цитата Сообщение от PiEy Посмотреть сообщение
    Чисто говоря, была такая проблема...
    Поток в потоке не завершается... Как то так, надо через какое то время его "ЕБАНУТЬ нхауй" а точнее перебать этот поток
    Крайне содержательный совет...

    Проблема заключается в процедуре TScriptThreadHelper.CallSyncFunc из SoulEngine, которая вызывает MAKE_STD_ZVAL несколько раз, для выделения памяти под переменную zend. Что бы освободить память, нужно дописать в TScriptThreadHelper.CallSyncFunc вот эти 4 строчки:

    efree(Args[1]);
    efree(Args[0]);
    efree(Return);
    efree(Func);


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

    Поэтому, как вариант, можно использовать этот способ, но вопрос остается открытым и мне бы все таки хотелось услышать мнение экспертов.

Метки этой темы

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения