Занимљиво

Разумевање поделе меморије у Делфима

Разумевање поделе меморије у Делфима

Назовите функцију „ДоСтацкОверфлов“ једном са свог кода и добићете ЕСтацкОверфлов грешка коју је Делпхи покренуо поруком "стацк оверфлов".

функција ДоСтацкОверфлов: цели број;

започети

резултат: = 1 + ДоСтацкОверфлов;

крај;

Шта је ово "стацк" и зашто тамо постоји преливање користећи горњи код?

Дакле, ДоСтацкОверфлов функција се рекурзивно позива - без „излазне стратегије“ - само се наставља вртећи и никада не престаје.

Брзо исправљање, то бисте требали учинити је да очистите очигледну грешку коју имате и осигурате да функција постоји у неком тренутку (тако да ваш код може наставити извршавати одакле сте функцију позвали).

Наставите даље и никад се не осврћете уназад, не марећи за грешку / изузетак као што је то сада решено.

Ипак, остаје питање: шта је овај стајк и зашто постоји преливање?

Меморија у вашим Делпхи апликацијама

Када покренете програмирање у Делпхију, можда ћете доживети грешку попут ове, решили бисте је и кренули даље. Овај се односи на расподелу меморије. Већину времена се не бисте бринули о подели меморије све док ослободите оно што креирате.

Како стекнете више искуства у Делпхију, започињете креирати сопствене часове, инстанцирати их, бринути се за управљање меморијом и слично.

Доћи ћете до точке када ћете у помоћи прочитати нешто попут "Локалне варијабле (декларисане у процедурама и функцијама) налазе се у апликацији стог." и такође Класе су референтни типови, па се при задатку не копирају, прослеђују се референцама и распоређују се на гомила.

Дакле, шта је "стацк" и шта је "хеап"?

Стацк вс. Хеап

Покретање апликације у Виндовс-у постоје три области у меморији у којима апликација чува податке: глобална меморија, хеап и стацк.

Глобалне променљиве (њихове вредности / подаци) се чувају у глобалној меморији. Меморија за глобалне променљиве резервисана је од ваше апликације када се програм покрене и остаје додељена док програм не престане. Меморија за глобалне променљиве назива се „сегмент података“.

Будући да се глобална меморија само једном додељује и ослобађа при прекиду програма, то нас у овом чланку не занима.

Стацк анд хеап су мјеста гдје се одвија динамичка додјела меморије: када креирате варијаблу за функцију, када створите инстанцу класе када пошаљете параметре функцији и користите / прослиједите вриједност резултата.

Шта је Стацк?

Када декларишете променљиву унутар функције, меморија потребна за држање променљиве додељује се из скупа. Једноставно напишете "вар к: интегер", користите "к" у својој функцији, а када функција изађе, не бринете о додељивању меморије нити ослобађању. Када варијабла изађе из обима (код напушта функцију), меморија која је узета у стог се ослобађа.

Меморија снопа распоређује се динамички користећи ЛИФО ("ласт ин фирст оут") приступ.

У Делпхи програмима се користи стоцк меморија

  • Локалне рутинске (метода, поступак, функција) променљиве.
  • Рутински параметри и типови повратка.
  • Виндовс АПИ функција позива.
  • Записи (зато не морате експлицитно да креирате инстанцу типа записа).

Не морате изричито ослободити меморију на снопу, јер се меморија аутоматски додељује вама магијом када, на пример, декларирате локалну променљиву функцију. Када функција изадје (понекад и пре захваљујући оптимизацији Делпхи компајлера) меморија за променљиву ће се аутоматски магично ослободити.

Величина меморијске стопе је, по дефаулту, довољно велика за ваше (толико сложене) Делпхи програме. Вредности „Максимална величина хрпе“ и „Минимална величина хрпе“ на Линкер опцијама за ваш пројекат одређују подразумеване вредности - у 99,99% ово не би требало да мењате.

Замислите гомилу као гомилу меморијских блокова. Када изјавите / употребите локалну променљиву, Делпхи менаџер меморије ће изабрати блок одозго, употребити га, а када више није потребан, вратит ће се назад у стог.

Употребљавајући локалну меморију променљивих која се користи из скупа, локалне променљиве се не иницијализирају када су деклариране. Прогласите променљиву „вар к: интегер“ у некој функцији и покушајте само прочитати вредност када уђете у функцију - к ће имати неку „чудну“ нулту вредност. Дакле, увек иницијализирајте (или поставите вредност) на ваше локалне променљиве пре него што прочитате њихову вредност.

Захваљујући ЛИФО-у, операције слагања (распоређивања меморије) су брзе јер је за управљање снопом потребно само неколико операција (пусх, поп).

Шта је хеап?

Хеап је регија меморије у коју се похрањује динамички распоређена меморија. Када креирате инстанцу класе, меморија се додељује из гомиле.

У Делпхи програмима хеап меморија користи / вхен

  • Креирање инстанције класе.
  • Израда и промјена величине динамичких низова.
  • Изричито додељивање меморије помоћу ГетМем, ФрееМем, Нев и Диспосе ().
  • Користећи АНСИ / широк / Уницоде жице, варијанте, интерфејсе (аутоматски управља Делпхи).

Хеап меморија нема леп изглед, тамо где би био ред да се додељују блокови меморије. Хеап изгледа као лименка мермера. Додјела меморије из хрпе је насумична, блок одавде него блок оданде. Стога су операције гомиле нешто спорије од оних на хрпи.

Када тражите нови меморијски блок (тј. Креирате инстанцу класе), Делпхи менаџер меморије ће то решити за вас: добићете нови меморијски блок или коришћени и одбачени.

Хрпа се састоји од читаве виртуалне меморије (РАМ-а и простора на диску).

Ручно распоређивање меморије

Сада када је све о меморији јасно, можете сигурно (у већини случајева) занемарити горе наведено и једноставно наставити писање Делпхи програма као што сте то јуче радили.

Наравно, требали бисте бити свјесни када и како ручно распоредити / ослободити меморију.

Подигнут је "ЕСтацкОверфлов" (с почетка чланка), јер се сваким позивом на ДоСтацкОверфлов користи нови сегмент меморије из снопа, а стацк има ограничења. Тако једноставна.