diff options
| author | Ryan Johnson <rjohnson@mozilla.com> | 2021-04-29 16:16:42 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-04-29 16:16:42 -0700 |
| commit | 95aca4b4d8fa62815d4bd412fff1a364f842814a (patch) | |
| tree | 5e57661720fe9058d5c7db637e764800b50f9060 /files/uk/web/javascript/memory_management | |
| parent | ee3b1c87e3c8e72ca130943eed260ad642246581 (diff) | |
| download | translated-content-95aca4b4d8fa62815d4bd412fff1a364f842814a.tar.gz translated-content-95aca4b4d8fa62815d4bd412fff1a364f842814a.tar.bz2 translated-content-95aca4b4d8fa62815d4bd412fff1a364f842814a.zip | |
remove retired locales (#699)
Diffstat (limited to 'files/uk/web/javascript/memory_management')
| -rw-r--r-- | files/uk/web/javascript/memory_management/index.html | 204 |
1 files changed, 0 insertions, 204 deletions
diff --git a/files/uk/web/javascript/memory_management/index.html b/files/uk/web/javascript/memory_management/index.html deleted file mode 100644 index 0022a81129..0000000000 --- a/files/uk/web/javascript/memory_management/index.html +++ /dev/null @@ -1,204 +0,0 @@ ---- -title: Керування пам'яттю -slug: Web/JavaScript/Memory_Management -tags: - - JavaScript - - Збирання сміття - - пам'ять - - продуктивність -translation_of: Web/JavaScript/Memory_Management ---- -<div>{{JsSidebar("Advanced")}}</div> - -<p>У низькорівневих мовах, наприклад C, існують примітивні функції для ручного керування пам'яттю, такі як <a href="https://pubs.opengroup.org/onlinepubs/009695399/functions/malloc.html">malloc()</a> та <a href="https://en.wikipedia.org/wiki/C_dynamic_memory_allocation#Overview_of_functions">free()</a>. В той же час JavaScript автоматично виділяє пам'ять при створенні об'єктів та звільняє її, коли вони більше не використовуються (<em>збирання сміття</em>). Ця автоматичність є потенційним джерелом плутанини: вона може дати розробникам хибне враження, що їм не потрібно хвилюватись щодо керування пам'яттю.</p> - -<h2 id="Життєвий_цикл_памяті">Життєвий цикл пам'яті</h2> - -<p>Незалежно від мови програмування, життєвий цикл пам'яті завжди приблизно той самий:</p> - -<ol> - <li>Виділення потрібної пам'яті</li> - <li>Використання виділеної пам'яті (читання, запис)</li> - <li>Вивільнення виділеної пам'яті, коли вона більше не потрібна</li> -</ol> - -<p>Друга частина в усіх мовах є явною. Перша та остання частини є явними у низькорівневих мовах, але, як правило, неявні у мовах високого рівня, таких як JavaScript.</p> - -<h3 id="Виділення_памяті_у_JavaScript">Виділення пам'яті у JavaScript</h3> - -<h4 id="Ініціалізація_значень">Ініціалізація значень</h4> - -<p>Щоб не турбувати розробника виділеннями пам'яті, JavaScript автоматично виділяє пам'ять, коли оголошуються початкові значення.</p> - -<pre class="brush: js">var n = 123; // виділяє пам'ять для числа -var s = 'блабла'; // виділяє пам'ять для рядка - -var o = { - a: 1, - b: null -}; // виділяє пам'ять для об'єкта та значень, що він містить - -// (як з об'єктом) виділяє пам'ять для масиву та -// значень, що він містить -var a = [1, null, 'аовл']; - -function f(a) { - return a + 2; -} // виділяє пам'ять для функції (об'єкт, який можна викликати) - -// функціональні вирази також виділяють пам'ять для об'єкта -someElement.addEventListener('click', function() { - someElement.style.backgroundColor = 'blue'; -}, false); -</pre> - -<h4 id="Виділення_памяті_через_виклики_функцій">Виділення пам'яті через виклики функцій</h4> - -<p>Виклики деяких функцій виділяють пам'ять під об'єкт.</p> - -<pre class="brush: js">var d = new Date(); // виділяє пам'ять під об'єкт Date - -var e = document.createElement('div'); // видділяє пам'ять під елемент DOM</pre> - -<p>Деякі методи виділяють пам'ять для нових значень чи об'єктів:</p> - -<pre class="brush: js">var s = 'йцуке'; -var s2 = s.substr(0, 3); // s2 - новий рядок -// Оскільки рядки є незмінними, -// JavaScript може вирішити не виділяти пам'ять, -// а лише зберегти діапазон [0, 3]. - -var a = ['ouais ouais', 'nan nan']; -var a2 = ['generation', 'nan nan']; -var a3 = a.concat(a2); -// новий масив з 4 елементів, що є -// поєданням елементів a та a2. -</pre> - -<h3 id="Використання_значень">Використання значень</h3> - -<p>Використання значень, по суті, означає читання та запис у виділеній пам'яті. Це можна зробити зчитуванням та записом значення змінної чи властивості об'єкта, чи навіть передачею аргументу у функцію.</p> - -<h3 id="Звільнення_памяті_коли_вона_більше_не_потрібна">Звільнення пам'яті, коли вона більше не потрібна</h3> - -<p>Більшість проблем керування пам'яттю виникають на цій стадії. Найскладніший аспект цього етапу полягає у визначенні, коли виділена пам'ять більше не потрібна. </p> - -<p>Низькорівневі мови вимагають, щоб розробник вручну визначав, у якій точці програми виділена пам'ять більше не потрібна, та звільняв її.</p> - -<p>Деякі високорівневі мови, такі як JavaScript, використовують форму автоматичного керування пам'яттю, відому як <a href="https://uk.wikipedia.org/wiki/%D0%97%D0%B1%D0%B8%D1%80%D0%B0%D0%BD%D0%BD%D1%8F_%D1%81%D0%BC%D1%96%D1%82%D1%82%D1%8F">збирання сміття</a> (ЗС). Збирач сміття відслідковує виділення пам'яті та визначає момент, коли блок виділеної пам'яті більше не потрібний, і повертає його. Цей автоматичний процес є неточним, оскільки загальна проблема визначення, чи потрібна наразі та чи інша ділянка пам'яті, є <a href="https://uk.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%96%D1%87%D0%BD%D0%B0_%D1%80%D0%BE%D0%B7%D0%B2%27%D1%8F%D0%B7%D0%BD%D1%96%D1%81%D1%82%D1%8C">нерозв'язною</a>.</p> - -<h2 id="Збирання_сміття">Збирання сміття</h2> - -<p>Як було зазначено вище, загальна проблема автоматичного визначення того, що якась ділянка пам'яті "більше не потрібна", є нерозв'язною. Як наслідок, збирачі сміття впроваджують обмеження вирішення загальної проблеми. Цей розділ пояснює концепції, необхідні для розуміння головних алгоритмів збирання сміття та відповідних обмежень.</p> - -<h3 id="Посилання">Посилання</h3> - -<p>Головна концепція, на яку покладаються алгоритми збирачів сміття - це концепція <em>посилань</em>. У контексті керування пам'яттю об'єкт посилається на інший об'єкт, якщо звертається до нього (явно чи неявно). Наприклад, об'єкт JavaScript має посилання на свій <a href="/uk/docs/Web/JavaScript/Inheritance_and_the_prototype_chain">прототип</a> (неявне посилання) та на значення своїх властивостей (явне посилання).</p> - -<p>У цьому контексті поняття "об'єкта" є ширшим, ніж звичайні об'єкти JavaScript, і містить також області видимості функцій (або глобальну область видимості).</p> - -<h3 id="Збирання_сміття_через_підрахунок_посилань">Збирання сміття через підрахунок посилань</h3> - -<p>Це найпримітивніший алгоритм збирання сміття. Цей алгоритм звужує проблему з визначення того, чи об'єкт досі є потрібним, до визначення того, чи мають інші об'єкти досі посилання на даний об'єкт. Об'єкт називається "сміттям", або підлягає збиранню, якщо на нього вказує нуль посилань.</p> - -<h4 id="Приклад">Приклад</h4> - -<pre class="brush: js">var x = { - a: { - b: 2 - } -}; -// Створено 2 об'єкта. Один має посилання у іншому як одна з його властивостей. -// Інший має посилання через присвоєння його змінній 'x'. -// Зрозуміло, що жоден з них не може бути прибраний. - - -var y = x; // Змінна 'y' - друга сутність, що має посилання на об'єкт. - -x = 1; // Тепер об'єкт, що початково був присвоєний 'x', має унікальне посилання, - // втілене у змінній 'y'. - -var z = y.a; // Посилання на властивість 'a' об'єкта. - // Цей об'єкт тепер має 2 посилання: одне у вигляді властивості, - // інше у вигляді змінної 'z'. - -y = 'mozilla'; // Об'єкт, що початково був присвоєний 'x', тепер має нуль посилань. - // Він може бути прибраний. - // Однак, на його властивість 'a' досі посилається - // змінна 'z', тому її не можна вивільнити. - -z = null; // Властивість 'a' об'єкта, що початково був присвоєний x, - // має нуль посилань. Об'єкт тепер може бути прибраний. -</pre> - -<h4 id="Обмеження_Циклічні_посилання">Обмеження: Циклічні посилання</h4> - -<p>Існує обмеження у випадку циклічних посилань. У наступному прикладі два об'єкти створені з властивостями, в яких вони посилаются один на одного, таким чином створюючи цикл. Вони вийдуть за межі області видимості, коли завершиться виклик функції. В цей момент вони стають непотрібними, і їхня виділена пам'ять має бути повернена. Однак, алгоритм, що підраховує посилання, не вважатиме їх готовими для повернення, оскільки кожен з двох об'єктів має принаймні одне посилання, що вказує на нього, в результаті жоден з них не позначається для збирання сміття. Циклічні посилання є типовою причиною витоків пам'яті.</p> - -<pre class="brush: js">function f() { - var x = {}; - var y = {}; - x.a = y; // x посилається на y - y.a = x; // y посилається на x - - return 'йцуке'; -} - -f(); -</pre> - -<h4 id="Приклад_з_реального_життя">Приклад з реального життя</h4> - -<p>Internet Explorer 6 та 7 відомі тим, що їхні збирачі сміття для об'єктів DOM працюють на основі підрахунку посилань. Цикли є типовою помилкою, що призводить до витоків пам'яті:</p> - -<pre class="brush: js">var div; -window.onload = function() { - div = document.getElementById('myDivElement'); - div.circularReference = div; - div.lotsOfData = new Array(10000).join('*'); -}; -</pre> - -<p>У наведеному прикладі DOM-елемент "myDivElement" має циклічне посилання на самого себе у властивості "circularReference". Якщо ця властивість не буде явно видалена чи обнулена, збирач сміття, що підраховує посилання, завжди матиме принаймні одне наявне посилання і триматиме DOM-елемент у пам'яті, навіть якщо він був видалений з DOM-дерева. Якщо DOM-елемент містить великий об'єм даних (проілюстровано у наведеному прикладі властивістю "lotsOfData"), пам'ять, зайнята цими даними, ніколи не буде вивільнена, що може призвести до проблем, пов'язаних з пам'яттю, наприклад, переглядач ставатиме все повільнішим.</p> - -<h3 id="Алгоритм_маркування_та_прибирання_mark-and-sweep">Алгоритм маркування та прибирання (mark-and-sweep)</h3> - -<p>Цей алгоритм звужує визначення "об'єкта, який більше не потрібен" до "недосяжного об'єкта".</p> - -<p>Даний алгоритм використовує набір об'єктів, що називаються <em>коренями. </em>У JavaScript корінь є глобальним об'єктом. Періодично збирач сміття починатиме від цих коренів, знаходитиме усі об'єкти, що мають посилання у коренях, далі усі об'єкти, що мають посилання у них, і т. д. Таким чином, починаючи від коренів, збирач сміття знайде усі <em>досяжні</em> об'єкти та збере усі недосяжні об'єкти.</p> - -<p>Цей алгоритм є покращенням попереднього, оскільки об'єкт, що має нуль посилань, є об'єктивно недосяжним. Протилежне не є істиною, як ми бачили на прикладі циклічних посилань.</p> - -<p>Станом на 2012 рік усі сучасні переглядачі використовують збирачі сміття з алгоритмом маркування та прибирання. Усі покращення в галузі збирання сміття у JavaScript (генераційне/інкрементне/конкурентне/паралельне збирання сміття) за останні кілька років є покращеннями реалізації даного алгоритму, а не покращеннями самого алгоритму збирання сміття чи скороченням його визначення моменту, коли "об'єкт більше не потрібен".</p> - -<h4 id="Циклічні_посилання_більше_не_є_проблемою">Циклічні посилання більше не є проблемою</h4> - -<p>У наведеному вище прикладі, коли завершується виклик функції, два об'єкти більше не мають посилань з жодного ресурсу, досяжного з глобального об'єкта. Як наслідок, збирач сміття визнає їх недосяжними та поверне виділену під них пам'ять.</p> - -<h4 id="Обмеження_Ручне_вивільнення_памяті">Обмеження: Ручне вивільнення пам'яті</h4> - -<p>Бувають випадки, коли було б зручно власноруч визначити, коли й яка пам'ять буде звільнена. Щоб звільнити пам'ять об'єкта, його треба зробити явно недосяжним.</p> - -<p>Станом на 2019 рік немає можливості явно чи програмно запустити збирання сміття у JavaScript.</p> - -<h2 id="Node.js">Node.js</h2> - -<p>Node.js пропонує додаткові можливості та інструменти для конфігурування та відлагодження проблем з пам'яттю, які можуть бути недоступні для JavaScript, що виконується у середовищі переглядача.</p> - -<h4 id="Прапори_рушія_V8">Прапори рушія V8</h4> - -<p>Максимальний розмір доступної пам'яті купи може бути збільшений за допомогою прапору:</p> - -<p><code>node --<em>max-old-space-size=6000</em> index.js</code></p> - -<p>Ми також можемо викликати збирач сміття для відлагодження проблем з пам'яттю, використовуючи прапор та <a href="https://nodejs.org/uk/docs/guides/debugging-getting-started/">Chrome Debugger</a>:</p> - -<pre class="brush: bash">node --expose-gc --inspect index.js</pre> - -<h4 id="Див._також">Див. також</h4> - -<ul> - <li><a class="external" href="http://www.ibm.com/developerworks/web/library/wa-memleak/">Стаття IBM про "Шаблони витоків пам'яті у JavaScript" (2007)</a></li> - <li><a class="external" href="http://msdn.microsoft.com/en-us/magazine/ff728624.aspx">Стаття Kangax про те, як зареєструвати обробник подій та запобігти витокам пам'яті (2010)</a></li> - <li><a href="/uk/docs/Mozilla/Performance" title="https://developer.mozilla.org/en-US/docs/Mozilla/Performance">Продуктивність</a></li> -</ul> |
