Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 22.09.2012, 17:50
Евгений79 Евгений79 вне форума
Прохожий
 
Регистрация: 24.04.2011
Сообщения: 24
Репутация: 156
По умолчанию Увеличивается расход памяти

Код:
procedure TForm1.Button1Click(Sender: TObject);
var
 list: TStringList;
 i: Integer;
 str,str2: string;
begin
 button1.Caption:='Start';
 list:= TStringList.Create;
 list.clear;
 str:='';
 for i:=0 to 200 do str:=str+IntToStr(i); //длина строки 493 символа.
 for i:=0 to 10000000 do
 begin
  list.Add(str);
 end;
 button1.Caption:='End';
list.Free;
end;

lmikle: пользуемся тегами!!!

Так все работает отлично. Память сильно не расходуется.
но если заменить строку list.Add(str);
на list.Add(str + '1');
или
str2:=str + '1';
list.Add(str2);


то приложение вылетает с руганью на окончание памяти.
А если так сделать
str2:=str;
list.Add(str2);

то тоже никаких проблем с памятью

win7 delphi 7 ram 8gb

Последний раз редактировалось lmikle, 23.09.2012 в 08:42.
Ответить с цитированием
  #2  
Старый 22.09.2012, 18:45
Аватар для YVitaliy
YVitaliy YVitaliy вне форума
Местный
 
Регистрация: 14.12.2011
Сообщения: 481
Версия Delphi: Borland Delphi7
Репутация: 17
По умолчанию

Вот смотри: ты добавляешь строку размером 493 символа (493 байта) 10000000 раз = 4930000000 байта пр. равн. 10 мб. А вот если ты еще каждый раз прибавишь по '1' в конец каждой строки, то размер будет
4930000000+10000000^2-(10000000^2-10000000)/2; Дальше считай сам
Ответить с цитированием
  #3  
Старый 22.09.2012, 22:40
robt robt вне форума
Активный
 
Регистрация: 17.02.2011
Сообщения: 297
Репутация: -1806
По умолчанию

Цитата:
Сообщение от Евгений79
win7 delphi 7 ram 8gb
ниповериш, 32битным приложениям насрать на ram 8gb
Ответить с цитированием
  #4  
Старый 23.09.2012, 03:15
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Евгений79
Так все работает отлично. Память сильно не расходуется.
но если заменить строку list.Add(str);
на list.Add(str + '1');
или
str2:=str + '1';
list.Add(str2);


то приложение вылетает с руганью на окончание памяти.
Это всё потому что String (точнее AnsiString) является типом с управляемым временем жизни со счётчиком ссылок.
Пример:
Код:
    str := StringOfChar('X', 1024 * 1024); // Создаём новую строку str размером в мегабайт
    str2 := str + '1'; // Создаём новую строку str2 и копируем в неё содержимое str плюс сивол '1'
    for i := 1 to 1000000 do
    begin
      list.Add(str2); // В список list добавляется миллион раз ссылка на строку str2
    end;
В этом примере только один раз выделяется память под строку str2 и в цикле в список list миллион раз добавляется ссылка на эту строку. Ссылка это просто указатель (Pointer), который в Win32 занимает всего 4 байта, что в сумме займёт 4*1000000=4000000 байт под эти указатели, плюс мегабайт для самой строки.

Другой пример:
Код:
    str := StringOfChar('X', 1024 * 1024); // Создаём новую строку str размером в мегабайт
    for i := 1 to 1000000 do
    begin
      str2 := str + '1'; // Создаём новую строку str2 и копируем в неё содержимое str плюс сивол '1'
      list.Add(str2); // В список list добавляется миллион раз ссылка на строку str2
    end;
В этом примере всё совсем по-другому. Здесь миллион раз выделяется память под новую строку и ссылка на неё добавляется в список list. Сколько займёт памяти миллион мегабайтных строк подсчитать не составит труда.
Ответить с цитированием
  #5  
Старый 24.09.2012, 14:08
Евгений79 Евгений79 вне форума
Прохожий
 
Регистрация: 24.04.2011
Сообщения: 24
Репутация: 156
По умолчанию

Да, я знаю что 32 бита больше 2 гигов рамы не увидит.

Спасибо. За развернутое пояснение.
Как можно избежать перерасхода памяти в моем примере?
Ответить с цитированием
  #6  
Старый 24.09.2012, 15:42
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Евгений79
Да, я знаю что 32 бита больше 2 гигов рамы не увидит.

Спасибо. За развернутое пояснение.
Как можно избежать перерасхода памяти в моем примере?
Ответ зависит от того, какую задачу твой пример пытается решить.
Ответить с цитированием
  #7  
Старый 24.09.2012, 16:08
Евгений79 Евгений79 вне форума
Прохожий
 
Регистрация: 24.04.2011
Сообщения: 24
Репутация: 156
По умолчанию

Создать огромный список неодинаковых строк.
Ответить с цитированием
  #8  
Старый 24.09.2012, 16:15
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Евгений79
Создать огромный список неодинаковых строк.
Чтобы этот список занял больше адресного пространства чем это позволяет Windows?
Ответить с цитированием
  #9  
Старый 24.09.2012, 16:47
Евгений79 Евгений79 вне форума
Прохожий
 
Регистрация: 24.04.2011
Сообщения: 24
Репутация: 156
По умолчанию

Все, понял. Не сразу дошел смысл вашего описания про указатели.
Спасибо.

Но кстати, да, интересно. Как обойти ограничение винды?
наверное, даже не винды, а 32 битной дельфи.
Ответить с цитированием
  #10  
Старый 24.09.2012, 16:51
robt robt вне форума
Активный
 
Регистрация: 17.02.2011
Сообщения: 297
Репутация: -1806
По умолчанию

Цитата:
Сообщение от Евгений79
Все, понял. Не сразу дошел смысл вашего описания про указатели.
Спасибо.

Но кстати, да, интересно. Как обойти ограничение винды?
наверное, даже не винды, а 32 битной дельфи.
писать\читать файл ёпт
Ответить с цитированием
  #11  
Старый 24.09.2012, 16:53
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
Смех

БД:
id: number; // номер строки
str: varchar; // строка
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #12  
Старый 24.09.2012, 17:06
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,907
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

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

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
  #13  
Старый 25.09.2012, 12:21
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Ещё можно воспользоваться интересной, но, насколько мне известно, редко используемой возможностью создания "Временных" временных файлов. Такой файл создаётся, но хранится не на диске, а в оперативной памяти пока её хватает и главное что при этом не ограничивается объёмом 2GB. Но даже когда закончится свободное место в оперативке, то такой файл будет частично сбрасываться на диск вместо того чтобы сообщать о нехватке памяти - главное чтобы было достаточно свободного места на диске.
Ответить с цитированием
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение:
~TB~ (25.09.2012)
  #14  
Старый 25.09.2012, 22:08
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Почему редко, очень даже часто используемая вохможность.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #15  
Старый 27.09.2012, 09:53
nixel nixel вне форума
Начинающий
 
Регистрация: 12.12.2011
Адрес: Москва
Сообщения: 150
Версия Delphi: XE2-U4
Репутация: 131
По умолчанию

Цитата:
Сообщение от Евгений79
Но кстати, да, интересно. Как обойти ограничение винды?
наверное, даже не винды, а 32 битной дельфи.

Возможно немного некропостинг, но как вариант - использовать свежие версии Delphi.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 12:31.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025