# Garbage Collection

## Introduction

* “Reachable” values are those that are accessible or usable somehow. They are guaranteed to be stored in memory.
* Garbage collection is performed automatically. We cannot force or prevent it.
* Objects are retained in memory while they are reachable.
* Being referenced is not the same as being reachable (from a root): a pack of interlinked objects can become unreachable as a whole, as we’ve seen in the example below

## Simple Example

```javascript
let user = {
  name: "John"
};

user = null;
```

* The object is created
* However after set to null, there is no reference on the object, so the object can be collected and free the memory

```javascript
// user has a reference to the object
let user = {
  name: "John"
};

let admin = user;

user = null;
```

* The object cannot be collected as it is referenced by admin unless we set admin to null too

## Interlinked objects

```javascript
function marry(man, woman) {
  woman.husband = man;
  man.wife = woman;

  return {
    father: man,
    mother: woman
  }
}

let family = marry({
  name: "John"
}, {
  name: "Ann"
});
```

![](https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2FCGKlW0BZ6jAkNl1BIdZU%2Fimage.png?alt=media\&token=8343c74e-7f49-4751-97fb-d67c2b06ef38)

* In order to delete the man , we need to remove family.father and family.mother.husband

![](https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2FnVlVVfM0urP3A16OHoAS%2Fimage.png?alt=media\&token=6bec2efc-0f9c-4689-94ca-a3f55384a83f)

![](https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2Fo942r8AAeahV7bg5PzRz%2Fimage.png?alt=media\&token=b13d2cee-bb48-4a23-8e52-b523e909d9ac)

* if we set family to null then, both woman and man can be collected

## GC Trace

```sh
node --trace-gc script.mjs
```

* It should output the following

```sh
[13973:0x110008000]       44 ms: Scavenge 2.4 (3.2) -> 2.0 (4.2) MB, 0.5 / 0.0 ms  (average mu = 1.000, current mu = 1.000) allocation failure
```

| Token value                                           | Interpretation                           |
| ----------------------------------------------------- | ---------------------------------------- |
| 13973                                                 | PID of the running process               |
| 0x110008000                                           | Isolate (JS heap instance)               |
| 44 ms                                                 | The time since the process started in ms |
| Scavenge                                              | Type / Phase of GC                       |
| 2.4                                                   | Heap used before GC in MB                |
| (3.2)                                                 | Total heap before GC in MB               |
| 2.0                                                   | Heap used after GC in MB                 |
| (4.2)                                                 | Total heap after GC in MB                |
| 0.5 / 0.0 ms (average mu = 1.000, current mu = 1.000) | Time spent in GC in ms                   |
| allocation failure                                    | Reason for GC                            |

## Types of GC

### Introduction

<figure><img src="https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2FbupH7UasDCB09SGVDGSa%2Fimage.png?alt=media&#x26;token=ba628e5f-c900-46d1-878b-4259f79d0ce7" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2FVUYPcG5BFzbW3nWS0kYn%2Fimage.png?alt=media&#x26;token=59c3644b-73b4-4f93-a132-5a61193b8471" alt=""><figcaption></figcaption></figure>

* Initially, objects are in the Nursery region.
* If they survive the first round of GC, they will be moved to the Intermediate region
* If they survive the second round of GC, they will be moved to the Old Generation region.
* For each generation, the algorithm is different:
  * Young generation — Minor GC (Scavenger)
  * Old generation — Major GC (Full Mark-Compact)

### Mark-sweep

<figure><img src="https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2FqtoP4asnSPwS7anzg1UX%2Fimage.png?alt=media&#x26;token=4b305551-1f9d-4068-883d-543894204216" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2FzQKO6B1fKnmrgXpsZ3xV%2Fimage.png?alt=media&#x26;token=24654635-4d91-4752-abd8-5dfac080b484" alt=""><figcaption></figcaption></figure>

1. Mark: mark the roots as “reachable”
2. Visit and recursively mark objects directly or indirectly referenced by roots as “reachable”
3. Sweep: unmarked ones are removed
4. Compaction:  To reuse the small and scattered memory gaps left behind by dead objects, we would process the “compact” task: copy surviving objects into other pages and free the old page.

### Scavenger <a href="#id-6355" id="id-6355"></a>

<figure><img src="https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2FGv390d3tzncoLipHGAUV%2Fimage.png?alt=media&#x26;token=5d763bec-34ce-4da1-98ab-3e1ecea819a8" alt=""><figcaption></figcaption></figure>

* Divided the young generation into two parts, we only have to limit the moving behavior within the page. Instead of focusing on the dead objects, we only focus on the surviving ones. We move all surviving objects to a contiguous chunk of memory within the page, and thus the from-space has become the “whole garbage.” Free the “From-Space” all!
* After moving, To-Space becomes From-Space and vice-versa. And the From-Space becomes empty, and new allocations can be done in the From-Space.
* Space for the young generation is limited to 16MB, and it would quickly reach its limit. Objects that survive a second GC are evacuated into the old generation rather than To-Space.

## Clean GC Manually

* Only work when expose-gc flag is available
* Here is an example

```javascript
global.gc();
console.log(process.memoryUsage());
let vm = new WeakMap();
let key = new Array(1000000);
vm.set(key,1);
global.gc();
console.log(process.memoryUsage());
key = null;
global.gc();
console.log(process.memoryUsage());
```

```sh
node --expose-gc index.js
```

## Reference

{% embed url="https://javascript.info/garbage-collection" %}

{% embed url="https://nodejs.org/en/learn/diagnostics/memory/using-gc-traces" %}

{% embed url="https://medium.com/better-programming/deep-dive-into-garbage-collection-in-javascript-6881610239a" %}

{% embed url="https://github.com/thlorenz/v8-perf/blob/master/gc.md#sample-scavenge-scenario" %}

{% embed url="https://blog.csdn.net/qq_42690194/article/details/124259852" %}
