<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[QUIK -> DDE &mdash; Реальное удаление элементов таблицы - как?]]></title>
		<link>https://quik2dde.ru/viewtopic.php?id=357</link>
		<atom:link href="https://quik2dde.ru/extern.php?action=feed&amp;tid=357&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «Реальное удаление элементов таблицы - как?».]]></description>
		<lastBuildDate>Fri, 10 Dec 2021 14:35:55 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: Реальное удаление элементов таблицы - как?]]></title>
			<link>https://quik2dde.ru/viewtopic.php?pid=3390#p3390</link>
			<description><![CDATA[<div class="quotebox"><cite>swerg пишет:</cite><blockquote><p>Из него видно, что даже после вызова <strong>collectgarbage </strong>память из-под таблицы, где были удалены элементы, не освобождается. Причем не освобождается вовсе. И видимо никогда (это про &quot;время от времени&quot;), пока таблица не будет полностью переинициализирована пустотой таблицей.<br />Так?</p></blockquote></div><p>высвобождается, ваш пример завершает работу раньше, чем сборщик мусора начал работать, заменил print на message и всё работает как надо <img src="https://quik2dde.ru/img/smilies/wink.png" width="15" height="15" alt="wink" /><br />т.е. 1 раз вызывать collectgarbage перед sleep вполне достаточно.</p>]]></description>
			<author><![CDATA[null@example.com (kalikazandr)]]></author>
			<pubDate>Fri, 10 Dec 2021 14:35:55 +0000</pubDate>
			<guid>https://quik2dde.ru/viewtopic.php?pid=3390#p3390</guid>
		</item>
		<item>
			<title><![CDATA[Re: Реальное удаление элементов таблицы - как?]]></title>
			<link>https://quik2dde.ru/viewtopic.php?pid=3389#p3389</link>
			<description><![CDATA[<p>О! эксперименты показали, что память из-под удаленных элементов таблицы <strong>освобождается</strong>, когда в таблицу <strong>добавляется новый элемент</strong>. Не заменяется значение уже имеющегося, а именно добавляется новый элемент.<br />До добавления новых элементов память, занятая таблицей, не освобождается, даже удалить почти все элементы из неё.</p><p>Пример:</p><div class="codebox"><pre><code>function get_t_count(t)
  local c = 0
  for n in pairs(t) do 
    c = c + 1
  end
  return c
end

t = {}
for i=1,10000 do
  t[i] = i * 11
end

print (1, collectgarbage(&quot;count&quot;) , get_t_count(t), &quot;&lt;&lt;-- создали, заполнили таблицу&quot;)

for i=1,9000 do
  table.remove(t, 1)
end

collectgarbage ()
print (2, collectgarbage(&quot;count&quot;) , get_t_count(t), &quot;&lt;&lt;-- удалили 90% элементов таблицы&quot;)

t[1] = 5.546

print (3, collectgarbage(&quot;count&quot;) , get_t_count(t), &quot;&lt;&lt;-- заменили значение t[1]&quot;)

t[20000] = 1

print (4, collectgarbage(&quot;count&quot;) , get_t_count(t), &quot;&lt;&lt;-- добавили элемент t[20000]&quot;)

local cnt = get_t_count(t)
for i=1,cnt*0.9 do
  table.remove(t, 1)
end

collectgarbage ()
print (5, collectgarbage(&quot;count&quot;) , get_t_count(t), &quot;&lt;&lt;-- удалили 90% элементов таблицы&quot;)

t[30000] = 1

print (6, collectgarbage(&quot;count&quot;) , get_t_count(t), &quot;&lt;&lt;-- добавили элемент t[30000]&quot;)</code></pre></div><p>Вывод:</p><div class="codebox"><pre><code>1    276.4326171875    10000    &lt;&lt;-- создали, заполнили таблицу
2    276.2353515625    1000     &lt;&lt;-- удалили 90% элементов таблицы
3    276.3271484375    1000     &lt;&lt;-- заменили значение t[1]
4    36.4140625        1001     &lt;&lt;-- добавили элемент t[20000]
5    36.2587890625     101      &lt;&lt;-- удалили 90% элементов таблицы
6    22.3720703125     102      &lt;&lt;-- добавили элемент t[30000]</code></pre></div><p>Во втором столбце (дробное значение) - это занятая в Lua память.</p><p>На шаге 2, после удаления элементов таблицы и вызова collectgarbage() - занятая память не уменьшилась.<br />На шаге 3 память тоже не уменьшилась, т.к. мы заменили значение для уже имеющегося в таблице элемента [1].<br />А вот на шаге 4 занятая данными память в Lua уменьшилась, хотя мы добавили в таблицу один новый элемент t[20000]. Но в это момент Lua наконец-то переаллоцировала память под таблицу и освободила место.</p>]]></description>
			<author><![CDATA[null@example.com (swerg)]]></author>
			<pubDate>Fri, 10 Dec 2021 11:05:48 +0000</pubDate>
			<guid>https://quik2dde.ru/viewtopic.php?pid=3389#p3389</guid>
		</item>
		<item>
			<title><![CDATA[Re: Реальное удаление элементов таблицы - как?]]></title>
			<link>https://quik2dde.ru/viewtopic.php?pid=3388#p3388</link>
			<description><![CDATA[<div class="quotebox"><cite>kalikazandr пишет:</cite><blockquote><p>Фишка в том, что созданные локально внутри блока таблицы при выходе из блока удаляются не сразу, а &quot;время от времени&quot;</p></blockquote></div><p>В моём понимании, при вызове <strong>collectgarbage</strong>() наступает то самое &quot;время от времени&quot;, ведь так? или я ошибаюсь?</p><div class="quotebox"><cite>kalikazandr пишет:</cite><blockquote><p>И без <strong>collectgarbage </strong>выделение памяти растет довольно таки быстро</p></blockquote></div><p>Это понятно.<br />Но в моём исходном примере <strong>collectgarbage </strong>есть! Предлагаю рассуждать именно в рамках приведенного мою примера.<br />Из него видно, что даже после вызова <strong>collectgarbage </strong>память из-под таблицы, где были удалены элементы, не освобождается. Причем не освобождается вовсе. И видимо никогда (это про &quot;время от времени&quot;), пока таблица не будет полностью переинициализирована пустотой таблицей.<br />Так?</p><p>И если это так - то в типичном для QUIK сценарии &quot;добавлять заявки в таблицу, после их исполнения удалять из таблицы&quot;, т.е. вести таблицу Lua со списком активных заявок, получается, что память под такую таблицу будет бесконечно расходоваться, без переиспользования.<br />И как тут быть?</p><p>Во всяком случае мне не удалось составить пример, где бы память Lua переиспользовалась для удаленных элементов таблицы.</p>]]></description>
			<author><![CDATA[null@example.com (swerg)]]></author>
			<pubDate>Fri, 10 Dec 2021 10:49:21 +0000</pubDate>
			<guid>https://quik2dde.ru/viewtopic.php?pid=3388#p3388</guid>
		</item>
		<item>
			<title><![CDATA[Re: Реальное удаление элементов таблицы - как?]]></title>
			<link>https://quik2dde.ru/viewtopic.php?pid=3383#p3383</link>
			<description><![CDATA[<div class="quotebox"><cite>swerg пишет:</cite><blockquote><p>Тогда, правда, мне все равно не понятен пример, который приводите вы. В самом ли деле в нем освобождается память из-под таблицы, из которой удалены часть элементов? надо будет поставить эксперимент.</p></blockquote></div><p>Фишка в том, что созданные локально внутри блока таблицы при выходе из блока удаляются не сразу, а &quot;время от времени&quot;<br />И без collectgarbage выделение памяти растет довольно таки быстро:<br /></p><div class="codebox"><pre><code>--memory_test.lua
local function test()
    local t = {}; return t
end
function main()
    while not exitflag do
        test()
        --collectgarbage()
        sleep(1)
    end
end
function OnStop()
    exitflag = true
end</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (kalikazandr)]]></author>
			<pubDate>Wed, 08 Dec 2021 22:54:47 +0000</pubDate>
			<guid>https://quik2dde.ru/viewtopic.php?pid=3383#p3383</guid>
		</item>
		<item>
			<title><![CDATA[Re: Реальное удаление элементов таблицы - как?]]></title>
			<link>https://quik2dde.ru/viewtopic.php?pid=3382#p3382</link>
			<description><![CDATA[<p>Спасибо за цитату.</p><p>&quot;<em>время от времени</em>&quot; - какая-то ну очень расплывчатая фраза.<br />А вот &quot;<em>для сбора мертвых <strong>объектов</strong></em>&quot; вероятно как раз полностью отвечает на вопрос. Видимо таблица целиком есть единый объект Lua, и пока она не пуста - память из под таблицы не освобождается.</p><p>Это что касается моего примера.</p><p>Тогда, правда, мне все равно не понятен пример, который приводите вы. В самом ли деле в нем освобождается память из-под таблицы, из которой удалены часть элементов? надо будет поставить эксперимент.</p>]]></description>
			<author><![CDATA[null@example.com (swerg)]]></author>
			<pubDate>Wed, 08 Dec 2021 17:40:02 +0000</pubDate>
			<guid>https://quik2dde.ru/viewtopic.php?pid=3382#p3382</guid>
		</item>
		<item>
			<title><![CDATA[Re: Реальное удаление элементов таблицы - как?]]></title>
			<link>https://quik2dde.ru/viewtopic.php?pid=3381#p3381</link>
			<description><![CDATA[<div class="quotebox"><cite>swerg пишет:</cite><blockquote><p>фраза &quot;сборщик мусора работает по времени&quot;. Могли бы ее растолковать чуть подробнее?</p></blockquote></div><p>&quot;Lua использует сборщик мусора, который запускается время от времени для сбора мертвых объектов, когда они больше не доступны из программы Lua.&quot;<br />Ключевое слово - время от времени и объекты, в вашем примере нет удаленных объектов.</p>]]></description>
			<author><![CDATA[null@example.com (kalikazandr)]]></author>
			<pubDate>Wed, 08 Dec 2021 15:21:44 +0000</pubDate>
			<guid>https://quik2dde.ru/viewtopic.php?pid=3381#p3381</guid>
		</item>
		<item>
			<title><![CDATA[Re: Реальное удаление элементов таблицы - как?]]></title>
			<link>https://quik2dde.ru/viewtopic.php?pid=3380#p3380</link>
			<description><![CDATA[<p><strong>kalikazandr</strong>, я не совсем понял ваш ответ, т.к. в нем присутствует&nbsp; main() и sleep(), характерные для квика.<br />Я же привожу пример для &quot;чистого&quot; Lua. И вопрос просто про Lua как таковое.<br />Ну т.е. пусть у нас просто Lua-скрипт, который долгое время сам по себе работает; таблица в нем заполняется, часть элементов удаляется, добавляются новые (без выхода из скрипта). Как тогда?</p><p>Или вы говорите о том, что&nbsp; collectgarbage() анализирует время, прошедшее с момента создания переменной и реально чистит из-под нее помять только про прошествии какого-то времени?<br />В самом деле: в Lua ведь нет отдельного потока, очищающего в фоне память, потому не очень понимаю что подразумевает фраза &quot;сборщик мусора работает по времени&quot;. Могли бы ее растолковать чуть подробнее?</p>]]></description>
			<author><![CDATA[null@example.com (swerg)]]></author>
			<pubDate>Wed, 08 Dec 2021 12:31:29 +0000</pubDate>
			<guid>https://quik2dde.ru/viewtopic.php?pid=3380#p3380</guid>
		</item>
		<item>
			<title><![CDATA[Re: Реальное удаление элементов таблицы - как?]]></title>
			<link>https://quik2dde.ru/viewtopic.php?pid=3379#p3379</link>
			<description><![CDATA[<div class="quotebox"><cite>swerg пишет:</cite><blockquote><p>И как же тогда быть? если в таблицу добавляем / удаляем элементы на протяжении работы скрипта - то занятая данными Lua память будет только расти и расти.</p><p>Есть ли способы реального освобождения памяти из-под элементов таблицы? гуглом ничего не сумел найти</p></blockquote></div><p>Привет! Таблицы созданные локально внутри блоков - тоже висят в памяти. <br />У вас все действия выполняются без задержек, а сборщик мусора работает по времени.<br /></p><div class="codebox"><pre><code>function main()
  while not exitflag do
    --some code--
   collectgarbage ()
   sleep(1)
  end
end</code></pre></div><p>такое размещение collectgarbage вполне справляется с очисткой памяти</p>]]></description>
			<author><![CDATA[null@example.com (kalikazandr)]]></author>
			<pubDate>Tue, 07 Dec 2021 21:14:48 +0000</pubDate>
			<guid>https://quik2dde.ru/viewtopic.php?pid=3379#p3379</guid>
		</item>
		<item>
			<title><![CDATA[Реальное удаление элементов таблицы - как?]]></title>
			<link>https://quik2dde.ru/viewtopic.php?pid=3378#p3378</link>
			<description><![CDATA[<p>Что происходит при удалении элемента таблицы Lua? Освобождается память?<br />Решил проверить, и наткнулся на очень неожиданно-грустный результат.</p><p>Скрипт для теста:</p><div class="codebox"><pre><code>function get_t_count(t)
  local c = 0
  for n in pairs(t) do 
    c = c + 1
  end
  return c
end

t = {}
for i=1,10000 do
  t[i] = i * 11
end

print (1, collectgarbage(&quot;count&quot;) , get_t_count(t), &quot;&lt;&lt;-- создали, заполнили таблицу&quot;)

for i=1,8000 do
  t[i] = nil
end

print (2, collectgarbage(&quot;count&quot;), get_t_count(t), &quot;&lt;&lt;-- присвоили nil для 80% элементов таблицы&quot;)
collectgarbage ()
print (3, collectgarbage(&quot;count&quot;) , get_t_count(t), &quot;&lt;&lt;-- почистили мусор&quot;)

for i=1,9000 do
  table.remove(t, 1)
end

print (4, collectgarbage(&quot;count&quot;) , get_t_count(t), &quot;&lt;&lt;-- удалили 90% элементов таблицы&quot;)
collectgarbage ()
print (5, collectgarbage(&quot;count&quot;) , get_t_count(t), &quot;&lt;&lt;-- почистили мусор&quot;)

t = {}
print (6, collectgarbage(&quot;count&quot;) , get_t_count(t), &quot;&lt;&lt;-- переинициализировали таблицу {}&quot;)
collectgarbage ()
print (7, collectgarbage(&quot;count&quot;) , get_t_count(t), &quot;&lt;&lt;-- почистили мусор&quot;)</code></pre></div><p>Это скрипт выводит:</p><div class="codebox"><pre><code>1    276.3134765625    10000   &lt;&lt;-- создали, заполнили таблицу
2    276.2890625       2000    &lt;&lt;-- присвоили nil для 80% элементов таблицы
3    276.1962890625    2000    &lt;&lt;-- почистили мусор
4    276.2880859375    2000    &lt;&lt;-- удалили 80% элементов таблицы
5    276.1962890625    2000    &lt;&lt;-- почистили мусор
6    276.3427734375    0       &lt;&lt;-- переинициализировали таблицу {}
7    20.1962890625     0       &lt;&lt;-- почистили мусор</code></pre></div><p>Во втором столбце у нас - объем использованной Lua памяти.<br />Получается, что ни присвоение <strong>nil </strong>элементам таблицы, ни удаление элементов из таблицы через<strong> table.remove</strong>() не освобождает память! Даже если вызываем <strong>collectgarbage</strong>()<br />Помогает лишь полная переинициализация (удаление) таблицы через t = {}</p><p>И как же тогда быть? если в таблицу добавляем / удаляем элементы на протяжении работы скрипта - то занятая данными Lua память будет только расти и расти.</p><p>Есть ли способы реального освобождения памяти из-под элементов таблицы? гуглом ничего не сумел найти</p>]]></description>
			<author><![CDATA[null@example.com (swerg)]]></author>
			<pubDate>Tue, 07 Dec 2021 09:45:26 +0000</pubDate>
			<guid>https://quik2dde.ru/viewtopic.php?pid=3378#p3378</guid>
		</item>
	</channel>
</rss>
