Категория > Новости > Сборка мусора. Разбираем мифы об автоматическом управлении памятью - «Новости»

Сборка мусора. Разбираем мифы об автоматическом управлении памятью - «Новости»


24-10-2020, 00:01. Автор: Evans
не даст сов­рать.

Бо­лее ред­кий вари­ант проб­лемы с висячим ука­зате­лем — пов­торное осво­бож­дение (double free), которое унич­тожа­ет полез­ные дан­ные.


Та­ким обра­зом, от решения для авто­мати­чес­кого управле­ния тре­буют­ся два свой­ства: никог­да не уда­лять из памяти объ­екты, на которые есть живые ука­зате­ли, и по воз­можнос­ти не оставлять в памяти объ­екты, на которые живых ука­зате­лей нет.


Что делает сборщик мусора?


Уп­рощен­но мож­но ска­зать, что при запус­ке у прог­раммы есть неп­рерыв­ный диапа­зон адре­сов, куда она может помес­тить свои дан­ные. Прог­рамма с авто­мати­чес­ким управле­нием памятью сра­зу при запус­ке зап­рашива­ет у ОС область памяти под «кучу» (heap). Началь­ный раз­мер кучи час­то (но не всег­да) мож­но нас­тро­ить во вре­мя ком­пиляции или выпол­нения. При выпол­нении прог­раммы раз­мер кучи может рас­ти.


Пос­ле это­го сбор­щик мусора пери­оди­чес­ки сле­дит за тем, какие учас­тки памяти еще содер­жат нуж­ные дан­ные, а какие мож­но осво­бодить и запол­нить новыми дан­ными. Как имен­но он это дела­ет — зависит от реали­зации, но об этом даль­ше. Для начала раз­веем более прос­тые мифы.


Сборщик мусора — часть языка?


Час­то мож­но услы­шать утвер­жде­ния вро­де «Ruby — язык со сбор­кой мусора» или «С — язык с руч­ным управле­нием памятью». Пер­вое утвер­жде­ние вер­но в том смыс­ле, что ни одна реали­зация Ruby не пре­дос­тавля­ет воз­можность управлять памятью вруч­ную.


Со вто­рым утвер­жде­нием слож­нее. Сбор­ка мусора не вхо­дит в спе­цифи­кацию язы­ка С. Тем не менее спе­цифи­кация ее и не зап­реща­ет. Спе­цифи­кация язы­ка ада так­же не навязы­вает авто­рам ком­пилято­ров какую-то кон­крет­ную модель управле­ния памятью, но некото­рые ком­пилято­ры при этом пре­дос­тавля­ют опци­аль­ный сбор­щик мусора.


Та­кие ком­пилято­ры С мне неиз­вес­тны, но на прак­тике авто­мати­чес­ки управлять памятью в прог­раммах на С впол­не воз­можно с помощью сто­рон­них биб­лиотек.


Для при­мера мы возь­мем Boehm GC. Это весь­ма зре­лый и фун­кци­ональ­ный про­дукт, который исполь­зовали или поныне исполь­зуют мно­жес­тво про­ектов: как при­ложе­ний (нап­ример, век­торный гра­фичес­кий редак­тор Inkscape), так и реали­заций язы­ков прог­рамми­рова­ния.


Используем Boehm GC


Мно­гие дис­три­бути­вы Linux пре­дос­тавля­ют пакет с Boehm GC в репози­тори­ях, чаще все­го под име­нем libgc. В Fedora его мож­но пос­тавить коман­дой sudo dnf install libgc-devel, в Debian — sudo apt-get install libgc-dev.


Для демонс­тра­ции мы напишем прог­рамму, которая неп­рерыв­но зап­рашива­ет память под мас­сив из тысячи целых чисел, но никог­да ее не осво­бож­дает. Если бы мы исполь­зовали для выделе­ния памяти клас­сичес­кий malloc(), это была бы хрес­томатий­ная утеч­ка памяти. Но мы обра­тим­ся не нап­рямую к ОС, а к менед­жеру памяти Boehm GC с помощью фун­кции GC_MALLOC() и пос­мотрим, что будет.



Перейти обратно к новости