Что такое сборщик мусора в программировании

В этой ста­тье — важ­ное поня­тие из ком­пью­тер­ной тео­рии. Читай­те, если хоти­те раз­би­рать­ся в устрой­стве ком­пью­те­ров и памя­ти. Осо­бен­но полез­но для бэкен­да и раз­ра­бот­ки высо­ко­на­гру­жен­ных систем.

Ситуация

Когда мы пишем про­грам­мы, мы обыч­но дей­ству­ем по тако­му прин­ци­пу:

  • если надо — объ­яв­ля­ем пере­мен­ную и хра­ним в ней дан­ные;
  • если пере­мен­ных нуж­но мно­го — дела­ем мно­го пере­мен­ных;
  • пере­мен­ные мож­но объ­яв­лять внут­ри цик­лов, а цик­лы вкла­ды­вать в дру­гие цик­лы;

В ито­ге наши про­грам­мы могут обра­ба­ты­вать сот­ни, тыся­чи и мил­ли­о­ны пере­мен­ных с чис­ла­ми и тек­стом, и для нас это в поряд­ке вещей. Ком­пью­тер, соб­ствен­но, и создан для того, что­бы обра­ба­ты­вать за нас эти мас­си­вы дан­ных.

Проблема

Когда мы объ­яв­ля­ем новую пере­мен­ную, под неё выде­ля­ет­ся кусок памя­ти, где она будет хра­нить­ся. Часто быва­ет такое, что даже если эта пере­мен­ная потом нигде не исполь­зу­ет­ся, то она всё рав­но зани­ма­ет место в памя­ти.

Если таких пере­мен­ных будет мно­го, то про­грам­ма может занять мно­го памя­ти. Когда память заби­ва­ет­ся, ком­пью­тер нач­нёт тор­мо­зить. Вся заня­тая память осво­бо­дит­ся толь­ко тогда, когда про­грам­му закро­ют, а до того вре­ме­ни всё будет тор­мо­зить.

👉 Осо­бен­но это опас­но на кон­трол­ле­рах или носи­мых устрой­ствах: там обыч­но мало памя­ти и её лег­ко запол­нить. А кон­трол­ле­ры управ­ля­ют не толь­ко умным домом, но и, напри­мер, само­лё­та­ми или про­мыш­лен­ны­ми стан­ка­ми. Если не поду­мать о памя­ти в кон­трол­ле­ре дви­га­те­ля само­лё­та, то у тебя на тре­тьем часу полё­та отка­жет дви­га­тель.

Решение — очистка мусора и управление памятью

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

В руч­ном режи­ме про­грам­мист сам сле­дит за каж­дой пере­мен­ной, объ­ек­том и сущ­но­стью. Когда объ­ект или пере­мен­ная боль­ше не нуж­ны, он пря­мо в коде пишет: «Этот готов, уно­си­те». Для это­го он исполь­зу­ет спе­ци­аль­ные команды-деструкторы, кото­рые уда­ля­ют пере­мен­ную и осво­бож­да­ют память. Теперь эту область памя­ти может взять себе дру­гая про­грам­ма или пере­мен­ная, тогда ресур­сы рас­хо­ду­ют­ся мак­си­маль­но эко­ном­но.

Авто­ма­ти­че­ский режим назы­ва­ет­ся сбор­кой мусо­ра. Это такая отдель­ная мини-программа внут­ри основ­ной про­грам­мы, кото­рая пери­о­ди­че­ски про­бе­га­ет по объ­ек­там и пере­мен­ным в коде и смот­рит, нуж­ны они или нет. Если нет — сбор­щик мусо­ра сам уда­ля­ет пере­мен­ную и осво­бож­да­ет память.

Особенности ручного управления

При руч­ной рабо­те с памя­тью про­грам­мист полу­ча­ет пол­ный кон­троль над ресур­са­ми и может в любой момент осво­бо­дить уже ненуж­ную память. Это зна­чит, что мож­но напи­сать такую про­грам­му, когда в сум­ме пере­мен­ным нуж­но 500 мега­байт памя­ти, но за счёт свое­вре­мен­но­го уда­ле­ния все­гда заня­ты толь­ко 100 мега­байт.

Руч­ное управ­ле­ние иде­аль­но для систем со сла­бы­ми ресур­са­ми и систем реаль­но­го вре­ме­ни — там, где про­грам­ма не име­ет пра­ва тор­мо­зить.

Вме­сте с тем такой под­ход тре­бу­ет высо­кой ква­ли­фи­ка­ции про­грам­ми­ста. Нуж­но точ­но знать, какая пере­мен­ная тебе нуж­на и когда; как устро­е­ны цик­лы тво­ей про­грам­мы; как рабо­та­ет про­цес­сор и куда он может посмот­реть в тот или иной момент.

Особенности автоматического сборщика

Авто­ма­ти­че­ский сбор­щик сам ходит по про­грам­ме во вре­мя испол­не­ния и акку­рат­но под­чи­ща­ет память, как толь­ко нахо­дит мусор.

Вро­де хоро­шо, но нет. Сбор­щик мусо­ра тоже рабо­та­ет неиде­аль­но:

❌ Сбор­щик уда­ля­ет толь­ко те пере­мен­ные, в кото­рых он уве­рен сто­про­цент­но. Если есть один шанс, что пере­мен­ная может когда-нибудь пона­до­бить­ся, — её остав­ля­ют в памя­ти. То есть эффек­тив­ность не сто­про­цент­ная.

❌ Сбор­щик — это отдель­ная про­грам­ма, кото­рая рабо­та­ет вме­сте с основ­ной. И ей тоже нуж­ны ресур­сы и про­цес­сор­ное вре­мя. Это замед­ля­ет рабо­ту основ­ной про­грам­мы. Как если бы убор­щик при­хо­дил в отде­ле­ние Сбер­бан­ка посре­ди рабо­че­го дня и застав­лял всех на два часа поки­нуть рабо­чие места, что­бы он тут про­вёл влаж­ную убор­ку.

❌ Если рабо­чей памя­ти очень мало, то сбор­щик будет рабо­тать посто­ян­но. Но ему тоже нуж­на своя память для рабо­ты. И может полу­чить­ся, что сбор­щик, напри­мер, зани­ма­ет 100 МБ, а осво­бож­да­ет 10 МБ. Может ока­зать­ся так, что без сбор­щи­ка про­грам­ма будет рабо­тать эффек­тив­нее.

Автоматические сборщики — добро или зло?

Тут у раз­ра­бот­чи­ков мне­ния раз­де­ля­ют­ся.

С точ­ки зре­ния быст­ро­дей­ствия сбор­щи­ки — одно­знач­но зло, пото­му что они все­гда замед­ля­ют рабо­ту. Есть ситу­а­ции, когда замед­ле­ние неза­мет­но, а быва­ет, когда оно кри­тич­но.

  • Напри­мер, если офис­ное при­ло­же­ние ино­гда под­ви­са­ет на пол­се­кун­ды, это почти никто не заме­ча­ет. Воз­мож­но, оно у вас под­ви­са­ет пря­мо сей­час.
  • А если на пол­се­кун­ды под­вис­нет кон­трол­лер ракет­но­го дви­га­те­ля, то эта раке­та поле­тит не в кос­мос, а в Вашинг­тон. Хью­стон, у нас про­бле­ма.

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

Что выбрать?

С выбо­ром инте­рес­ная ситу­а­ция.

Если вы пише­те при­ло­же­ния для iOS или OSX, вам нель­зя исполь­зо­вать сбор­щи­ки мусо­ра из сооб­ра­же­ний быст­ро­дей­ствия.

Язы­ки типа JavaScript и Ruby соби­ра­ют мусор сами, вы об этом може­те даже нико­гда не узнать.

В неко­то­рые язы­ки мож­но под­клю­чить сбор мусо­ра, пожерт­во­вав про­из­во­ди­тель­но­стью — напри­мер, в Java, C или C++.

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

Чисто не там, где не сорят, а на хорошем рабочем месте
В про­грам­ми­ро­ва­нии как хоти­те, но на нор­маль­ной рабо­те в ИТ-компаниях мусор за вами уби­ра­ют убор­щи­ки. При­хо­ди­те в Прак­ти­кум, что­бы потом прий­ти на нор­маль­ную рабо­ту.