|
|
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
Я понимаю, что в литературе всё это описано, но иногда не получается найти ответы (обычно знаешь где искать уже когда знаешь ответ). Сильно не бейте за безграмотность в программировании, я любитель. Я в программе постоянно в огромных количествах работаю с записями состоящими из динамических массивов очень глубокой вложенности и размеров. Так же бывают классы с глубокой вложенностью других классов; Записи по сути представляют из себя описание конструкции с множеством параметров: Абстрактный пример, на случай если у вас есть претензии к самой структуре, у меня другая конструкция, но суть такая же Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. С выделением памяти особых проблем нет (если не выделил - сразу словишь ошибку и поправишь), то вот с высвобождением есть вопросы; 1. Если у меня динамические массивы глубокой вложенности, тот воспользовавшись SetLenght(Array,0) никаких потерь памяти не будет? Вопрос возник после прочтения данной темы https://www.programmersforum.ru/showthread.php?t=126357 2. Если у меня динамический массив классов, если после выделения памяти класса уменьшу массив - память станет недоступна (утечка)? Очистка созданных классов обязательна перед уменьшением массива? Пример Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 3.1. При создании в классе агрегированых классов (ClassB) Код: pascal 1. 2. 3. При использовании ClassA.Free (или Destroy) будет ли опустошена память которую я выделил под ClassB сама? На данный момент я делаю так: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Это корректно? Или излишне? 3.2. То же что и 3.1 но если дело будет в потоке, когда поток будет завершен - очиститься ли память от всяких созданных в нем классов, или тоже надо дополнять деструктор? 4. Чуть на другую тему - у меня в Delphi 7 при завершении кода в потоке память не очищается, надо дополнительно использовать Thread.Free; В Делфи 10 такой проблемы нет, после завершения кода память высвобождается. Как в Delphi 7 корректно очистить память после завершения кода потока? (никак не перееду на Delphi 10 ибо раздражают эти мигающие и дергающиеся окошки при компиляции при работе на нескольких мониторах) 5. FreeAndNil применительно к вопросам выше - очистит ли память от агрегированных классов автоматом, если нет - вызовет ли переназначенный деструктор? 6. Если я хочу очистить запись со вложенными динамическими массивами (без классов) до состояния, которое было при её создании, что нужно сделать? Finalize сбросит ли размеры массивов до нулевых? Вроде как через указатели и Get/FreeMem можно, но насколько это корректно? Можно, конечно, создать темповый массив и присваивать его обнуляемому, но как-то костыльно. 7. Ну и вопрос, наверное даже на отдельную тему, но может есть простое решение. Можно ли как нибудь в 32 битной системе решить проблему ограничением на размеры массива. Один элемент массива в памяти занимает 200-300 мегабайт: в скомпилированном в Delphi 7 приложении: после 7го увеличения массива вылетает OutOfMemory; в скомпилированном в Delphi 10 (32 bit) - где-то посл 25го - OutOfMemory; в скомпилированной в Delphi 10 (64 bit) - открывает сколько угодно (ну сотню точно) Можно ли как-то решить данную проблему без компиляции в 64битной делфе, так как интерцейс новой делфи мне пока не очень нравится? Кто-то писал про какие-то распределенные массивы (не понял что это). Может через указатели? И без использования БД! :) Я понимаю, что наиболее логичным мне ответом было бы: - "Иди книжки/Хелп читай". Но в книгах как-то уж очень часто такие вещи опускаются как очевидные, а хелп - это просто уничтожитель времени, зашел, просидел пол дня, ничего не понял :). Заранее огромное спасибо тем, кто заглянул сюда. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2019, 16:24 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
Андрей Игоревич, Вот здесь есть очень наглядный пример: https://programmersforum.ru/showthread.php?t=126357 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2019, 17:06 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
Андрей Игоревич, 1. Всё почистится, утечек не будет 2. Массив будет освобождён, объекты повиснут в памяти 3.1. Объекты сами не очистятся, нужно удалять в деструкторе. Проверка на NIL лишняя 3.2. Тот же ответ, что и в 3.1. 4. У потока есть свойство FreeOnTerminate 5. FreeAndNil это то же самое, что и Free, но дополнительно обнуляет переменную. Ничего дополнительно очищать не будет (ну в исходники-то можно заглянуть, а? 6. Finalize зачистит поля только управляемых типов (строки, дин. массивы, интерфейсы, варианты), все остальные поля остануться неизменёнными. Если требуется полное обнуление, то после Finalize нужно вызвать FillChar 7. Поддержка 64 бит появилась уже в XE2, не обязательно десятку ставить. Вместо массивов можно навелосипедить абстракцию, которая будет иметь интерфейс массива, а внутри раскладывать элементы по блокам и хранить список блоков (например, массив размером в 1000 элементов, при размере блока в 256 элементов, будет замещён в 4 блоках). Но без дженериков напляшешься пользоваться такими структурами. А если брать версию, где есть дженерики... то уж лучше 64 бита :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2019, 17:11 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
Kazantsev AlexeyПроверка на NIL лишняяЕсли вызывать Free. А у него Destroy ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2019, 17:23 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_, Точно, не доглядел. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2019, 17:24 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
GerasimenkoАндрей Игоревич, Вот здесь есть очень наглядный пример: https://programmersforum.ru/showthread.php?t=126357 Андрей Игоревич1. Если у меня динамические массивы глубокой вложенности, тот воспользовавшись SetLenght(Array,0) никаких потерь памяти не будет? Вопрос возник после прочтения данной темы https://www.programmersforum.ru/showthread.php?t=126357 Ну так этож та же тема, и там пишут - что не освобождается (или я чего не понял). Но Kazantsev AlexeyАндрей Игоревич, 1. Всё почистится, утечек не будет Непонятно... Kazantsev AlexeyПроверка на NIL лишняя Проверка на nil на случай если я не создал объект (я там их сотнями создаю и уничтожаю в процессе, в конце только часть существует). А хотя Free и так проверяет на nil..., ну тогда да, хотя что-то у меня с этим было неприятное, с тех пор проверяю. Kazantsev Alexey У потока есть свойство FreeOnTerminate Точно, как я о нем забыл... По тестирую. Kazantsev AlexeyFinalize зачистит поля только управляемых типов (строки, дин. массивы, интерфейсы, варианты), все остальные поля остануться неизменёнными. Если требуется полное обнуление, то после Finalize нужно вызвать FillChar Тут главный вопрос - сбросит ли сами размеры дин масивов до нуля. Kazantsev Alexey7. Поддержка 64 бит появилась уже в XE2, не обязательно десятку ставить. Вместо массивов можно навелосипедить абстракцию, которая будет иметь интерфейс массива, а внутри раскладывать элементы по блокам и хранить список блоков (например, массив размером в 1000 элементов, при размере блока в 256 элементов, будет замещён в 4 блоках). Но без дженериков напляшешься пользоваться такими структурами. А если брать версию, где есть дженерики... то уж лучше 64 бита :) Как-то сложновато и нерационально на первый взгляд. А есть 10я версия делфи сопоставимая по удобности и интерфейсу с 7кой с кучей плагинов (цветные линии, подсветка выделенных переменных, куча всего по мелочи)? И можно сделать, чтоб 10ка при компиляции не сходила с ума масштабируя себя 10 раз (зачем-то перебрасывает окно на основной монитор, затем растягивает, затем ещё что-то делает) и тратя на это в 10 раз больше времени, чем на компиляцию? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2019, 17:33 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
Андрей Игоревич, https://programmersforum.ru/showthread.php?t=126357 Оттуда Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. Проверте на своем массиве ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2019, 17:38 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
Андрей ИгоревичНепонятно... http://docwiki.embarcadero.com/RADStudio/Rio/en/Dynamic_array#Dynamic_Arrays Dynamic arrays of length 0 have the value nil. Так понятнее? Андрей ИгоревичТут главный вопрос - сбросит ли сами размеры дин масивов до нуля. Я же написал, что зачистит. Андрей ИгоревичА есть 10я версия делфи сопоставимая по удобности и интерфейсу с 7кой с кучей плагинов (цветные линии, подсветка выделенных переменных, куча всего по мелочи)? Понятия не имею, я всю эту светомузыку отключаю. Андрей ИгоревичИ можно сделать, чтоб 10ка при компиляции не сходила с ума масштабируя себя 10 раз (зачем-то перебрасывает окно на основной монитор, затем растягивает, затем ещё что-то делает) и тратя на это в 10 раз больше времени, чем на компиляцию? Можно поставить не десятку и жить спокойно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2019, 17:45 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
Gerasimenko, Освобождаемая память очищаться не обязана. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2019, 17:48 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
Kazantsev AlexeyGerasimenko, Освобождаемая память очищаться не обязана.И? Пример то как раз и хорош! Я бы даже сказал, отличный. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2019, 17:51 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
GerasimenkoИ? Пример то как раз и хорош! Я бы даже сказал, отличный. Если память освободили, но не очистили, она ещё сколько угодно будет сохранять прежние данные, пока они не будут затёрты новыми. А код зашибись, конечно. Читать по протухшему указателю это прям то что нужно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2019, 18:01 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
Kazantsev AlexeyGerasimenkoИ? Пример то как раз и хорош! Я бы даже сказал, отличный. Если память освободили, но не очистили, она ещё сколько угодно будет сохранять прежние данные, пока они не будут затёрты новыми. А код зашибись, конечно. Читать по протухшему указателю это прям то что нужно.На грабли легко наступить, как выше Вам писали авторЕсли вызывать Free. А у него Destroy Грабли: они везде расставлены... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2019, 18:03 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
GerasimenkoНа грабли легко наступить, как выше Вам писали Ага, только там всё-же Free оказался. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2019, 18:12 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
Андрей ИгоревичТут главный вопрос - сбросит ли сами размеры дин масивов до нуля. Finalize ничего не делает с размерами массивов, она просто проходится по всем вложенным массивам и записям и освобождает память, занятую под управляемые типы (string, interface и т.п.). Причём только освобождает (т.е. уменьшает счётчики ссылок и делает FreeMem() при необходимости), ЕМНИП она даже не изменяет сами значения полей. SetLength(SomeArray, 0) вызывает Finalize автоматом, если знает что в массиве есть управляемые типы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2019, 19:23 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
И можно сделать, чтоб 10ка при компиляции не сходила с ума масштабируя себя 10 раз (зачем-то перебрасывает окно на основной монитор, затем растягивает, затем ещё что-то делает) и тратя на это в 10 раз больше времени, чем на компиляцию? В заголовке Delphi есть выпадающий список desktop-ов. Когда Вы открыли проект, то у Вас скорее всего установлен desktop "Default Layout". Затем Вы запускаете проект на отладку, и у Вас меняется desktop на "Debug Layout". По какой то причине, у Вас в этом Desktop-е окно Delphi настроено на расположение в другом мониторе. Соответственно, в режиме отладки переместите среду Delphi на тот монитор, который Вам нужен, потом нажмите на кнопочку рядом с выпадающим списком desktop-ов и выберите Save desktop. После этого, расположение окон в desktop-е "Default Layout" сравняется с desktop-ом "Debug Lauout". И после этого, у Вас при запуске проекта на отладку перестанут дергаться окошки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2019, 20:14 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
Kazantsev AlexeyАндрей ИгоревичА есть 10я версия делфи сопоставимая по удобности и интерфейсу с 7кой с кучей плагинов (цветные линии, подсветка выделенных переменных, куча всего по мелочи)? Понятия не имею, я всю эту светомузыку отключаю. Помню-помню, настоящие программисты пишут код исключительно в блокноте - остальное от лукавого :). Просто привык уже этому и сильно ускоряет поиск ошибок. Kazantsev Alexey http://docwiki.embarcadero.com/RADStudio/Rio/en/Dynamic_array#Dynamic_Arrays Dynamic arrays of length 0 have the value nil.Так понятнее?alekcvpАндрей ИгоревичТут главный вопрос - сбросит ли сами размеры дин масивов до нуля. Finalize ничего не делает с размерами массивов, она просто проходится по всем вложенным массивам и записям и освобождает память, занятую под управляемые типы (string, interface и т.п.). Причём только освобождает (т.е. уменьшает счётчики ссылок и делает FreeMem() при необходимости), ЕМНИП она даже не изменяет сами значения полей. SetLength(SomeArray, 0) вызывает Finalize автоматом, если знает что в массиве есть управляемые типы. Понял, спасибо, просто не был уверен, что это делается на всю глубину. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.10.2019, 10:32 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
Короче. Есть управляемые типы - дин.массивы, строки. Их освобождение - за компилятором. Вручную можно освободить присвоив соответственно nil или '' либо setlength(0). В записях тоже работает это правило, и все управляемые поля записи также освобождаются автоматом - об этом заботится Finalize. Есть классы, которые надо создавать и удалять самому. ТС-у: первой строкой в проекте сделай ReportMemoryLeaksOnShutdown := True; и не гадай на кофейной гуще. А еще лучше - скачай FastMM, подключи его первым модулем в файле проекта и в FastMM4Options.inc в строке {.$define FullDebugModeWhenDLLAvailable} удали точку. Тогда будешь детально видеть, есть ли утечка и что конкретно утекло ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.10.2019, 10:56 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
...продолжается дезинформационная кампания, совмещенная с вирусной рекламой фастмм4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.10.2019, 11:06 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
ёёёёё...продолжается дезинформационная кампания, совмещенная с вирусной рекламой фастмм4. "Когда вы говорите, Иван Васильевич, такое впечатление, что вы бредите" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.10.2019, 11:24 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
А как именно FreeOnTerminate завершает поток и очищает память? Пример: В делфи7 я могу открыть в потоке 7 массивов за раз. Если FreeOnTerminate:=false и перед вызовом массива я предварительно FreeAndNil(Thread) - то я могу раз за разом открывать эти 7 массивов; Если FreeOnTerminate:=true и я ничего не делают перед очередным переотркытием файлов - то 7 я уже отрыть не могу, вылетает ошибка нехватки памяти. Но если открывать по одному (и, вероятно, по 6), то хоть 7, хоть 100 - ничего не вылетает. Итого получается, что FreeOnTerminate оставляет что-то в памяти, но потом как-то высвобождает (при вызове?)... Ну и при FreeOnTerminate проверка Thread<>nil - проходит, но при вызове чего бы то ни было (free,Terminate), вылетает ошибка. Как оно работает? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.10.2019, 17:34 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
Мда. FreeOnTerminate освобождает память, фактически вызывает MyThread.Free. Никакой связи с тем. что там в потоке делалось тут нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.10.2019, 17:42 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
"Объект" потока и собственно поток имеют только тут связь, что первое удобно инкапсулирует управление вторым. Но не более того. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.10.2019, 17:43 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
Андрей ИгоревичА как именно FreeOnTerminate завершает поток и очищает память? Пример: В делфи7 я могу открыть в потоке 7 массивов за раз. Если FreeOnTerminate:=false и перед вызовом массива я предварительно FreeAndNil(Thread) - то я могу раз за разом открывать эти 7 массивов; Если FreeOnTerminate:=true и я ничего не делают перед очередным переотркытием файлов - то 7 я уже отрыть не могу, вылетает ошибка нехватки памяти. Но если открывать по одному (и, вероятно, по 6), то хоть 7, хоть 100 - ничего не вылетает. Итого получается, что FreeOnTerminate оставляет что-то в памяти, но потом как-то высвобождает (при вызове?)... Ну и при FreeOnTerminate проверка Thread<>nil - проходит, но при вызове чего бы то ни было (free,Terminate), вылетает ошибка. Как оно работает? FreeOnTerminate := True просто автоматом вызывает TThread.Destroy() после того как завершится выполнение TThread.Execute(). Всё что вы там выделили внутри этого потока - вам же и освобождать в своём деструкторе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.10.2019, 18:14 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
alekcvp Андрей ИгоревичА как именно FreeOnTerminate завершает поток и очищает память? Пример: В делфи7 я могу открыть в потоке 7 массивов за раз. Если FreeOnTerminate:=false и перед вызовом массива я предварительно FreeAndNil(Thread) - то я могу раз за разом открывать эти 7 массивов; Если FreeOnTerminate:=true и я ничего не делают перед очередным переотркытием файлов - то 7 я уже отрыть не могу, вылетает ошибка нехватки памяти. Но если открывать по одному (и, вероятно, по 6), то хоть 7, хоть 100 - ничего не вылетает. Итого получается, что FreeOnTerminate оставляет что-то в памяти, но потом как-то высвобождает (при вызове?)... Ну и при FreeOnTerminate проверка Thread<>nil - проходит, но при вызове чего бы то ни было (free,Terminate), вылетает ошибка. Как оно работает? FreeOnTerminate := True просто автоматом вызывает TThread.Destroy() после того как завершится выполнение TThread.Execute(). Всё что вы там выделили внутри этого потока - вам же и освобождать в своём деструкторе. Я несколько не о том (или о том). Примитивный код: unit1 Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. unit2 Код: pascal 1. 2. 3. 4. 5. По факту - Thread.Free не делает поток Nil Thread.FreeOnTerminate:=True; - тоже не делает поток nil. насколько я понимаю - они только обнуляют все данные, если у меня в потоке создаются огромные массивы - они остаются, занимая память (хотя и обновляются) (в компиляторе их можно прощелкать на всю глубину и посмотреть на нули) Ну и соответственно проверка на nil тоже не проходит, поток не nil, но вызвать free - уже нельзя, вылетит ошибка памяти ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2019, 17:38 |
|
||
|
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
|
|||
|---|---|---|---|
|
#18+
Андрей ИгоревичПо факту - Thread.Free не делает поток Nil Естественно не делает. Не забота объекта следить сколько у тебя указателей на него. Ты их можешь присвоить хоть миллион, хоть миллиард. Сам наплодил - самому и очищать. Это азы работы с указателями. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2019, 17:45 |
|
||
|
|

start [/forum/topic.php?fid=58&msg=39883803&tid=2038666]: |
0ms |
get settings: |
5ms |
get forum list: |
10ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
142ms |
get topic data: |
6ms |
get forum data: |
2ms |
get page messages: |
36ms |
get tp. blocked users: |
1ms |
| others: | 206ms |
| total: | 412ms |

| 0 / 0 |
