Heim  >  Artikel  >  Web-Frontend  >  Vertiefte Kenntnisse der JavaScript-Speicherverwaltung und der GC-Algorithmen

Vertiefte Kenntnisse der JavaScript-Speicherverwaltung und der GC-Algorithmen

WBOY
WBOYnach vorne
2022-07-26 13:50:321985Durchsuche

Dieser Artikel vermittelt Ihnen relevante Kenntnisse über Javascript. Er erläutert hauptsächlich den Garbage-Collection-Mechanismus und die häufig verwendeten Garbage-Collection-Algorithmen Management, ich hoffe, es wird für alle hilfreich sein.

Vertiefte Kenntnisse der JavaScript-Speicherverwaltung und der GC-Algorithmen

[Verwandte Empfehlungen: Javascript-Video-Tutorial, Web-Frontend]

Vorwort

JavaScript reserviert beim Erstellen von Variablen (Arrays, Zeichenfolgen, Objekte usw.) automatisch Speicher und nicht, wenn Mit ihnen wird der zugewiesene Inhalt „automatisch“ freigegeben. Die JavaScript-Sprache unterscheidet sich von anderen Low-Level-Sprachen wie der C-Sprache und bietet Speicherverwaltungsschnittstellen wie malloc() für die Zuweisung aller Der benötigte Speicherplatz, free() gibt den zuvor zugewiesenen Speicherplatz frei. malloc()用于分配所需的内存空间、free()释放之前所分配的内存空间。

我们将释放内存的过程称为垃圾回收,像JavaScript这种高级语言提供了内存自动分配和自动回收,因为这个自动就导致许多开发者不会去关心内存管理。

即使高级语言提供了自动内存管理,但是我们也需要对内管管理有一下基本的理解,有时候自动内存管理出现了问题,我们可以更好的去解决它,或者说使用代价最小的方法解决它。

内存的生命周期

其实不管是什么语言,内存的声明周期大致分为如下几个阶段:

下面我们对每一步进行具体说明:

  • 内存分配:当我们定义变量时,系统会自动为其分配内存,它允许在程序中使用这块内存。
  • 内存使用:在对变量进行读写的时候发生
  • 内存回收:使用完毕后,自动释放不需要内存,也就是由垃圾回收机制自动回收不再使用的内存

JavaScript中的内存分配

为了保护开发人员的头发,JavaScript在定义变量时就自动完成了内存分配,示例代码如下:

let num = 123 // 给数值变量分配内存
let str = '一碗周' // 给字符串分配内存

let obj = {
  name: '一碗周',
  age: 18,
} // 给对象及其包含的值分配内存

// 给数组及其包含的值分配内存(类似于对象)
let arr = [1, null, 'abc']

function fun(a) {
  return a + 2
} // 给函数(可调用的对象)分配内存

// 函数表达式也能分配一个对象
Element.addEventListener(
  'click',
  event => {
    console.log(event)
  },
  false,
)

有些时候并不会重新分配内存,如下面这段代码:

// 给数组及其包含的值分配内存(类似于对象)
let arr = [1, null, 'abc']

let arr2 = [arr[0], arr[2]]
// 这里并不会重新对分配内存,而是直接存储原来的那份内存

在JavaScript中使用内存

JavaScript中使用值的过程实际上是对分配内存进行读取与写入的操作。这里的读取与写入可能是写入一个变量、读取某个变量的值、写入一个对象的属性值以及为函数传递参数等。

释放内存

JavaScript中的内存释放是自动的,释放的时机就是某些值(内存地址)不在使用了,JavaScript就会自动释放其占用的内存。

其实大多数内存管理的问题都在这个阶段。在这里最艰难的任务就是找到那些不需要的变量。

虽然说现在打高级语言都有自己垃圾回收机制,虽然现在的垃圾回收算法很多,但是也无法智能的回收所有的极端情况,这就是我们为什么要学习内存管理以及垃圾回收算法的理由了。

接下来我们来讨论一下JavaScript中的垃圾回收以及常用的垃圾回收算法。

JavaScript中的垃圾回收

前面我们也说了,JavaScript中的内存管理是自动的,在创建对象时会自动分配内存,当对象不在被引用或者不能从根上访问时,就会被当做垃圾给回收掉。

JavaScript中的可达对象简单的说就是可以访问到的对象,不管是通过引用还是作用域链的方式,只要能访问到的就称之为可达对象。可达对象的可达是有一个标准的,就是必须从根上出发是否能被找到;这里的根可以理解为JavaScript中的全局变量对象,在浏览器环境中就是window、在Node环境中就是global

为了更好的理解引用的概念,看下面这一段代码:

let person = {
  name: '一碗周',
}
let man = person
person = null

图解如下:

根据上面那个图我们可以看到,最终这个{ name: '一碗周' } Wir nennen

den Prozess der Speicherfreigabe

Hochsprachen wie JavaScript bieten automatische Zuweisung und

automatische 🎜 Wiederverwertung. Aufgrund dieser Automatisierung kümmern sich viele Entwickler nicht um die Speicherverwaltung. 🎜🎜Auch wenn Hochsprachen eine automatische Speicherverwaltung bieten, müssen wir dennoch über ein grundlegendes Verständnis der internen Verwaltung verfügen. Manchmal gibt es ein Problem mit der automatischen Speicherverwaltung, und wir können es besser lösen oder die kostengünstigste Methode verwenden . Lösen Sie es. 🎜🎜Speicherlebenszyklus🎜🎜🎜Tatsächlich ist der Speicherdeklarationszyklus unabhängig von der Sprache grob in die folgenden Phasen unterteilt:🎜🎜

🎜🎜🎜Wir erklären Ihnen jeden Schritt im Folgenden im Detail:🎜🎜

  • 🎜Speicherzuweisung: 🎜Wenn wir eine Variable definieren, weist das System ihr automatisch Speicher zu, was die Verwendung dieses Speichers im Programm ermöglicht.
  • 🎜Speichernutzung: 🎜Tritt beim Lesen und Schreiben von Variablen auf 🎜
  • 🎜Speicherrecycling: 🎜Nach der Verwendung wird unnötiger Speicher automatisch freigegeben, d. h. durch die Garbage Collection wird der Mechanismus automatisch recycelt Speicher, der nicht mehr verwendet wird

Speicherzuweisung in JavaScript

🎜🎜Um die Haare der Entwickler zu schützen, vervollständigt JavaScript beim Definieren von Variablen automatisch die Speicherzuweisung. Beispiel: Der Code lautet wie folgt : 🎜🎜
function groupObj(obj1, obj2) {
  obj1.next = obj2
  obj2.prev = obj1

  return {
    obj1,
    obj2,
  }
}
let obj = groupObj({ name: '大明' }, { name: '小明' })
🎜🎜Manchmal wird Speicher nicht neu zugewiesen, wie zum Beispiel der folgende Code: 🎜🎜
delete obj.obj1
delete obj.obj2.prev

Speicher in JavaScript verwenden

🎜Der Prozess der Verwendung von Werten in JavaScript ist tatsächlich die Zuweisung von Speicherlese- und -schreibvorgängen. Das Lesen und Schreiben kann hier das Schreiben einer Variablen, das Lesen des Werts einer Variablen, das Schreiben des Attributwerts eines Objekts und das Übergeben von Parametern an eine Funktion usw. sein. 🎜

Speicher freigeben

🎜Die Speicherfreigabe in JavaScript erfolgt automatisch, wenn bestimmte Werte (Speicheradressen) nicht mehr verwendet werden und JavaScript den von ihm belegten Speicher automatisch freigibt. 🎜🎜Tatsächlich treten die meisten Speicherverwaltungsprobleme in dieser Phase auf. Die schwierigste Aufgabe besteht hier darin, die Variablen zu finden, die nicht benötigt werden. 🎜🎜Obwohl Hochsprachen jetzt über eigene Garbage-Collection-Mechanismen verfügen und es viele Garbage-Collection-Algorithmen gibt, können sie nicht alle Extremsituationen intelligent recyceln. Aus diesem Grund müssen wir Speicherverwaltung und Garbage-Collection-Algorithmen erlernen. 🎜🎜Als nächstes besprechen wir die Garbage Collection in JavaScript und häufig verwendete Garbage Collection-Algorithmen. 🎜🎜Garbage Collection in JavaScript🎜🎜Wie bereits erwähnt, erfolgt die Speicherverwaltung in JavaScript automatisch, wenn auf ein Objekt nicht mehr verwiesen wird oder nicht mehr über das 🎜root🎜 zugegriffen werden kann als Müll recycelt werden. 🎜🎜Ein erreichbares Objekt in JavaScript ist einfach ein Objekt, auf das zugegriffen werden kann🎜, sei es über eine Referenz oder eine Bereichskette, solange darauf zugegriffen werden kann, wird es als erreichbares Objekt bezeichnet. Es gibt einen Standard für die Erreichbarkeit erreichbarer Objekte, das heißt, ob sie vom Stamm aus gefunden werden können. Der Stamm kann hier als globales Variablenobjekt in JavaScript verstanden werden, das in der Browserumgebung window ist. code>, In der Node-Umgebung ist es <code>global. 🎜🎜🎜Um das Konzept des Zitats besser zu verstehen, schauen Sie sich den folgenden Code an: 🎜🎜
// { name: &#39;一碗周&#39; } 的引用计数器 + 1
let person = {
  name: &#39;一碗周&#39;,
}
// 又增加了一个引用,引用计数器 + 1
let man = person
// 取消一个引用,引用计数器 - 1
person = null
// 取消一个引用,引用计数器 - 1。此时 { name: &#39;一碗周&#39; } 的内存就会被当做垃圾回收
man = null
🎜🎜Das Diagramm sieht wie folgt aus: 🎜🎜

🎜🎜Gemäß dem Bild oben können wir sehen, dass am Ende dieser { name: 'A bowl of Zhou ' wird nicht als Müll erfasst, da es noch eine Referenz hat. 🎜🎜🎜Lassen Sie uns nun die erreichbaren Objekte verstehen. Der Code lautet wie folgt: 🎜🎜

function groupObj(obj1, obj2) {
  obj1.next = obj2
  obj2.prev = obj1

  return {
    obj1,
    obj2,
  }
}
let obj = groupObj({ name: &#39;大明&#39; }, { name: &#39;小明&#39; })

调用groupObj()函数的的结果obj是一个包含两个对象的一个对象,其中obj.obj1next属性指向obj.obj2;而obj.obj2prev属性又指向obj.obj2。最终形成了一个无限套娃。

如下图:

现在来看下面这段代码:

delete obj.obj1
delete obj.obj2.prev

我们删除obj对象中的obj1对象的引用和obj.obj2中的prev属性对obj1的引用。

图解如下:

此时的obj1就被当做垃圾给回收了。

GC算法

GC是Garbage collection的简写,也就是垃圾回收。当GC进行工作的时候,它可以找到内存中的垃圾、并释放和回收空间,回收之后方便我们后续的进行使用。

在GC中的垃圾包括程序中不在需要使用的对象以及程序中不能再访问到的对象都会被当做垃圾。

GC算法就是工作时查找和回收所遵循的规则,常见的GC算法有如下几种:

  • 引用计数:通过一个数字来记录引用次数,通过判断当前数字是不是0来判断对象是不是一个垃圾。
  • 标记清除:在工作时为对象添加一个标记来判断是不是垃圾。
  • 标记整理:与标记清除类似。
  • 分代回收:V8中使用的垃圾回收机制。

引用计数算法

引用计数算法的核心思想就是设置一个引用计数器,判断当前引用数是否为0 ,从而决定当前对象是不是一个垃圾,从而垃圾回收机制开始工作,释放这块内存。

引用计数算法的核心就是引用计数器 ,由于引用计数器的存在,也就导致该算法与其他GC算法有所差别。

引用计数器的改变是在引用关系发生改变时就会发生变化,当引用计数器变为0的时候,该对象就会被当做垃圾回收。

现在我们通过一段代码来看一下:

// { name: &#39;一碗周&#39; } 的引用计数器 + 1
let person = {
  name: &#39;一碗周&#39;,
}
// 又增加了一个引用,引用计数器 + 1
let man = person
// 取消一个引用,引用计数器 - 1
person = null
// 取消一个引用,引用计数器 - 1。此时 { name: &#39;一碗周&#39; } 的内存就会被当做垃圾回收
man = null

引用计数算法的优点如下:

  • 发现垃圾时立即回收;
  • 最大限度减少程序暂停,这里因为发现垃圾就立刻回收了,减少了程序因内存爆满而被迫停止的现象。

缺点如下:

  • 无法回收循环引用的对象;

就比如下面这段代码:

function fun() {
  const obj1 = {}
  const obj2 = {}
  obj1.next = obj2
  obj2.prev = obj1
  return &#39;一碗周&#39;
}
fun()

上面的代码中,当函数执行完成之后函数体的内容已经是没有作用的了,但是由于obj1obj2都存在不止1个引用,导致两种都无法被回收,就造成了空间内存的浪费。

  • 时间开销大,这是因为引用计数算法需要时刻的去监控引用计数器的变化。

标记清除算法

标记清除算法解决了引用计数算法的⼀些问题, 并且实现较为简单, 在V8引擎中会有被⼤量的使⽤到。

在使⽤标记清除算法时,未引用对象并不会被立即回收.取⽽代之的做法是,垃圾对象将⼀直累计到内存耗尽为⽌.当内存耗尽时,程序将会被挂起,垃圾回收开始执行.当所有的未引用对象被清理完毕 时,程序才会继续执行.该算法的核心思想就是将整个垃圾回收操作分为标记和清除两个阶段完成。

第一个阶段就是遍历所有对象,标记所有的可达对象;第二个阶段就是遍历所有对象清除没有标记的对象,同时会抹掉所有已经标记的对象,便于下次的工作。

为了区分可用对象与垃圾对象,我们需要在每⼀个对象中记录对象的状态。 因此, 我们在每⼀个对象中加⼊了⼀个特殊的布尔类型的域, 叫做marked。 默认情况下, 对象被创建时处于未标记状态。 所以, marked 域被初始化为false

进行垃圾回收完毕之后,将回收的内存放在空闲链表中方便我们后续使用。

标记清除算法最大的优点就是解决了引用计数算法无法回收循环引用的对象的问题 。就比如下面这段代码:

function fun() {
  const obj1 = {},
    obj2 = {},
    obj3 = {},
    obj4 = {},
    obj5 = {},
    obj6 = {}
  obj1.next = obj2

  obj2.next = obj3
  obj2.prev = obj6

  obj4.next = obj6
  obj4.prev = obj1

  obj5.next = obj4
  obj5.prev = obj6
  return obj1
}
const obj = fun()

当函数执行完毕后obj4的引用并不是0,但是使用引用计数算法并不能将其作为垃圾回收掉,而使用标记清除算法就解决了这个问题。

Der Markierungs- und Löschalgorithmus weist auch Mängel auf. Auch wenn der Markierungs- und Löschalgorithmus zum Auffinden von Müllobjekten verwendet wird, kann er nicht sofort gelöscht werden und muss gelöscht werden zweites Mal.

Markierungs- und Sortieralgorithmus

Der Markierungs- und Sortieralgorithmus kann als erweiterte Version des Markierungs- und Löschalgorithmus betrachtet werden und seine Schritte sind ebenfalls in zwei Phasen unterteilt: Markieren und Löschen.

Aber in der Löschphase des Markierungssortieralgorithmus wird zuerst sortiert, die Position des Objekts verschoben und schließlich gelöscht.

Die Schritte sind wie folgt:

Speicherverwaltung in V8

Was ist V8?

V8 ist eine Mainstream-JavaScript-Ausführungs-Engine. Jetzt verwenden Node.js und die meisten Browser V8 als JavaScript-Engine. Die Kompilierungsfunktion von V8 verwendet die Just-in-Time-Kompilierung, die auch als dynamische Übersetzung oder Laufzeitkompilierung bezeichnet wird. Dabei handelt es sich um eine Methode zum Ausführen von Computercode, bei der die Kompilierung während der Programmausführung (während der Ausführung) und nicht vor der Ausführung erfolgt.

Die V8-Engine hat eine Obergrenze für den Speicher. Die Obergrenze liegt bei 1,5 GB unter einem 64-Bit-Betriebssystem und die Obergrenze bei 800 MB unter einem 32-Bit-Betriebssystem. Der Hauptgrund für die Festlegung der Speicherobergrenze ist, dass die Content-V8-Engine hauptsächlich für Browser vorbereitet ist und nicht für große Räume geeignet ist. Ein weiterer Punkt ist, dass die Speicherbereinigung dieser Größe sehr schnell ist und der Benutzer fast keine Zeit hat kein Gefühl, wodurch das Benutzererlebnis erhöht wird.

V8-Garbage-Collection-Strategie

Der V8-Motor übernimmt die Idee des Generationsrecyclings, das unser Gedächtnis nach bestimmten Regeln hauptsächlich in zwei Kategorien unterteilt: eine ist der Speicherbereich der neuen Generation und die andere ist der Speicherbereich der alten Generation .

Objekte der neuen Generation sind Objekte mit kurzer Überlebenszeit. Sie unterstützen normalerweise nur eine bestimmte Kapazität (32 MB für 64-Bit-Betriebssysteme und 16 MB für 32-Bit-Betriebssysteme). Objekte der alten Generation sind Objekte mit langem Überlebensereignis oder residentem Speicher. Einfach ausgedrückt handelt es sich um Objekte, die nach der Speicherbereinigung der neuen Generation überlebt haben.

Das folgende Bild zeigt den Speicher in V8:

Die V8-Engine verwendet je nach Objekt unterschiedliche GC-Algorithmen. Die in V8 häufig verwendeten GC-Algorithmen sind wie folgt:

  • Generationsrecycling
  • Leerzeichen kopieren
  • Markierung löschen
  • Markierung sortieren
  • Markierung erhöhen

Objektbereinigung der neuen Generation

Wie wir oben ebenfalls vorgestellt haben, speichert die neue Generation Objekte mit kurzer Überlebenszeit. Der Objektrecyclingprozess der neuen Generation verwendet einen Kopieralgorithmus und einen Markierungssortieralgorithmus.

Der Kopieralgorithmus unterteilt unseren Speicherbereich der neuen Generation in zwei Räume gleicher Größe. Wir nennen den aktuell verwendeten Zustandsraum den Von-Zustand und den Raumzustandsraum den Bis-Zustand :

Wir speichern alle aktiven Objekte im From-Bereich. Wenn der Speicherplatz fast voll ist, wird die Speicherbereinigung ausgelöst.

Zunächst müssen Sie die aktiven Objekte im Von-Bereich der neuen Generation markieren und organisieren. Nachdem die Markierung abgeschlossen ist, kopieren Sie die markierten aktiven Objekte in den Nach-Bereich und tauschen schließlich den Von-Bereich und den Nach-Bereich aus Raum. .

Eine weitere Sache, die erwähnt werden muss, ist, dass beim Kopieren von Objekten Objekte der neuen Generation in Objekte der alten Generation verschoben werden.

Für diese verschobenen Objekte gelten bestimmte Bedingungen:

Objekte der neuen Generation, die eine Runde der Speicherbereinigung überleben, werden in Objekte der alten Generation verschoben.

    Wenn die Raumbelegung 25 % überschreitet, wird dieses Objekt verschoben wird auch auf das Objekt der alten Generation verschoben (25 % des Grundes liegt darin, dass es Angst davor hat, die spätere Speicherzuweisung zu beeinträchtigen)
  • Wir können also sehen, dass die Speicherbereinigungsmethode für Objekte der neuen Generation darin besteht, Raum gegen Zeit auszutauschen.
Müllsammlung von Objekten der alten Generation

Im Bereich der alten Generation gespeicherte Objekte sind Objekte, die eine lange Überlebenszeit haben und einen großen Raum einnehmen. Gerade wegen seiner langen Überlebenszeit und seines großen Platzbedarfs kann der Replikationsalgorithmus nicht verwendet werden. Wenn der Replikationsalgorithmus verwendet wird, führt dies zu langer Zeit und Platzverschwendung.

Objekte der alten Generation verwenden im Allgemeinen Markierungslösch-, Markierungssortierungs- und inkrementelle Markierungsalgorithmen für die Speicherbereinigung.

In der Löschphase wird der Markierungs- und Löschalgorithmus hauptsächlich zum Recycling verwendet. Nach einiger Zeit wird eine große Anzahl diskontinuierlicher Speicherfragmente generiert. Wenn zu viele Fragmente nicht genügend Speicher zuweisen können, wird dies der Fall sein verwendet werden, um uns von Weltraumschrott zu befreien.

Die Garbage Collection von Objekten der alten Generation verwendet den inkrementellen Markierungsalgorithmus, um den Garbage Collection-Prozess zu optimieren. Der inkrementelle Markierungsalgorithmus ist in der folgenden Abbildung dargestellt:

Da JavaScript Single-Threaded ist, können nur eine Programmausführung und eine Garbage Collection gleichzeitig ausgeführt werden. Dies führt dazu, dass das Programm einfriert, wenn die Garbage Collection ausgeführt wird, was dem Benutzer definitiv ein schlechtes Erlebnis beschert.

Daher wird eine inkrementelle Markierung vorgeschlagen. Wenn das Programm ausgeführt wird, führt es zunächst eine vorläufige Markierung durch. Diese Markierung markiert möglicherweise nur direkt erreichbare Objekte und läuft dann für einen bestimmten Zeitraum weiter Zeit und Inkremente, also die Markierung, welche Objekte indirekt erreichbar sind. Wiederholen Sie dies bis zum Ende.

Leistungstool

Da JavaScript uns keine API zum Betreiben des Speichers zur Verfügung stellt, können wir uns nur auf die von ihm selbst bereitgestellte Speicherverwaltung verlassen, wissen aber nicht, wie die tatsächliche Speicherverwaltung aussieht. Manchmal müssen wir die Speichernutzung im Auge behalten. Das Performance-Tool bietet verschiedene Möglichkeiten, den Speicher zu überwachen.

Schritte zur Leistungsnutzung

Zuerst öffnen wir den Chrome-Browser (hier verwenden wir den Chrome-Browser, andere Browser sind ebenfalls akzeptabel), geben unsere Zieladresse in die Adressleiste ein, öffnen dann die Entwicklertools und wählen das Bedienfeld [Leistung].

Wählen Sie das Leistungsfeld aus und schalten Sie die Aufzeichnungsfunktion ein, greifen Sie dann auf die spezifische Schnittstelle zu, imitieren Sie den Benutzer, um einige Vorgänge auszuführen, stoppen Sie dann die Aufzeichnung und schließlich können wir die aufgezeichneten Speicherinformationen in der Analyseschnittstelle analysieren.

Reflexionen von Speicherproblemen

Die Haupterscheinungen von Speicherproblemen sind wie folgt:

  • Die Seite wird verzögert geladen oder häufig angehalten, und ihre unterste Ebene wird von der Ausführung einer häufigen Speicherbereinigung begleitet. Warum? ? Eine häufige Speicherbereinigung kann durch Code verursacht werden, der direkt dazu führt, dass der Speicher voll ist und eine sofortige Speicherbereinigung erfordert.

In Bezug auf dieses Problem können wir den Grund anhand des Speicheränderungsdiagramms analysieren:

    Die Seite weist weiterhin eine schlechte Leistung auf, was bedeutet, dass wir während unserer Nutzung ein schlechtes Gefühl haben. Das denken wir im Allgemeinen Unten wird es eine
  • Speichererweiterung geben. Die sogenannte Speichererweiterung besteht darin, dass die aktuelle Seite viel mehr Speicher beansprucht, als sie benötigt, als unser Gerät selbst benötigt bieten können, können wir zu diesem Zeitpunkt ein kontinuierlich schlechtes Leistungserlebnis wahrnehmen.
Das Problem, das die Speichererweiterung verursacht, kann ein Problem mit unserem Code sein, oder es kann sein, dass das Gerät selbst fehlerhaft ist. Wenn wir es analysieren, lokalisieren und lösen möchten, müssen wir wiederholte Tests auf mehreren Geräten durchführen

    Mit der Zeit wird die Leistung der Seite immer schlechter und die Ladezeit wird immer länger. Der Grund für dieses Problem kann ein Code-Speicherleck sein.
  • Um festzustellen, ob ein Speicherverlust vorliegt, können wir unseren Speicher über die
  • Memory Total View
überwachen. Wenn der Speicher weiter zunimmt, ist möglicherweise ein Speicherverlust aufgetreten. So überwachen Sie den Speicher Häufige Speicherbereinigung

Als Nächstes erklären wir diese Methoden separat.

Task-Manager überwacht den Speicher

Drücken Sie die Tasten [Umschalt] + [ESC] im Browser, um den vom Browser bereitgestellten Task-Manager zu öffnen. In der Im Bild oben können wir sehen, dass der [Speicherplatz] auf der Registerkarte [Nuggets] den vom DOM dieser Seite im Browser belegten Speicher darstellt. Wenn er weiter zunimmt, bedeutet dies, dass ein neues DOM erstellt wird Der folgende [Von JavaScript verwendete Speicher] (standardmäßig nicht aktiviert, muss durch Klicken mit der rechten Maustaste aktiviert werden) stellt den Heap in JavaScript dar, und die Größe in Klammern stellt alle erreichbaren Objekte in JavaScript dar.

    Timeline zeichnet den Speicher auf
  • Der im oben beschriebenen Browser bereitgestellte Task-Manager kann uns nur dabei helfen, festzustellen, ob ein Problem mit der Seite vorliegt, er kann das Problem mit der Seite jedoch nicht lokalisieren.
  • Timeline ist eine kleine Registerkarte im Performance-Tool, die die Situation auf der Seite in Millisekunden aufzeichnet, was uns helfen kann, Probleme leichter zu lokalisieren.
  • Heap-Snapshot, um getrennte DOMs zu finden
  • Heap-Snapshots dienen dazu, herauszufinden, ob im aktuellen Schnittstellenobjekt einige getrennte DOMs vorhanden sind. Das Vorhandensein von getrennten DOMs bedeutet, dass ein Speicherverlust vorliegt.

Zuerst müssen wir die verschiedenen Zustände von DOM herausfinden:

Zuerst existiert das DOM-Objekt im DOM-Baum, der zum normalen DOM gehört

Dann, wenn es nicht im existiert DOM-Baum und es gibt keine JS-Referenz, dies gehört zu Garbage. DOM-Objekte müssen recycelt werden. Schließlich sind sie nicht im DOM-Baum vorhanden, aber es gibt JS-Referenzen. Dies ist das abgetrennte DOM und wir müssen es manuell freigeben.

Schritte zum Auffinden getrennter DOMs: Öffnen Sie die Entwicklertools → [Speicherbereich] → [Benutzerkonfiguration] → [Snapshot abrufen] → Geben Sie

in [Filter] ein, um getrennte DOMs zu finden,

wie in der Abbildung unten gezeigt:

Nachdem wir das erstellte getrennte DOM gefunden haben, finden wir den Verweis auf das DOM und geben es dann frei.

Bestimmen Sie, ob eine häufige Speicherbereinigung erfolgt.

Da die Anwendung gestoppt wird, wenn GC ausgeführt wird, ist die Zeit zu lang und die Seite wird sehr unfreundlich, was dazu führt, dass die Anwendung blockiert wird angezeigt wird und sagt: „Ich bin im Status“. Sie werden das Gefühl haben, dass die Anwendung während der Verwendung hängen bleibt.

Wir können wie folgt beurteilen, ob eine häufige Speicherbereinigung erfolgt:

  • Verwenden Sie das Zeitleisten-Timingdiagramm, um den Speichertrend im aktuellen Leistungsbereich zu beurteilen und zu überwachen, wenn er häufig steigt und fällt , Es kommt zu einer häufigen Speicherbereinigung. Zu diesem Zeitpunkt müssen Sie den Code suchen, um festzustellen, was diese Situation bei der Ausführung verursacht hat.
  • Es wird einfacher, den Browser-Task-Manager zu verwenden. Die wichtigsten Änderungen im Task-Manager sind häufige sofortige Erhöhungen und Verringerungen sowie eine häufige Speicherbereinigung.

【Verwandte Empfehlungen: Javascript-Video-Tutorial, Web-Frontend

Das obige ist der detaillierte Inhalt vonVertiefte Kenntnisse der JavaScript-Speicherverwaltung und der GC-Algorithmen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:jb51.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen