>  기사  >  웹 프론트엔드  >  V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.

V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.

青灯夜游
青灯夜游앞으로
2022-04-27 20:44:483006검색

이 기사는 V8 엔진의 메모리 관리 및 가비지 수집 알고리즘을 이해하는 데 도움이 되기를 바랍니다.

V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.

우리 모두 알고 있듯이 JS는 자동으로 가비지 수집을 관리하므로 개발자는 메모리 할당 및 재활용에 대해 걱정할 필요가 없습니다. 또한 가비지 수집 메커니즘은 프런트엔드 인터뷰에서 일반적으로 테스트되는 부분이기도 합니다. 이 기사에서는 주로 V8의 세대별 가비지 수집 알고리즘에 대해 설명합니다. 이 기사를 읽고 나면 친구들이 V8 가비지 수집 메커니즘에 대해 고통할 수 있기를 바랍니다. painful). 이 기사에서는 주로 다음 내용을 다룹니다: <code>V8垃圾回收机制有个痛彻(哈哈,是痛彻!!!)的了解,文章主要涵盖如下内容:

  • V8的内存限制与解决办法
  • 新生代内存对象的Scavenge算法
  • 基于可达性分析算法标记存活对象的逻辑以及优化手段
  • 新生代内存对象的晋升条件、
  • Scavenge算法的深度/广度优先区别
  • 跨代内存的的写屏障
  • 老生代内存对象的标记清除/整理算法
  • GCSTW原因及优化策略

V8的内存限制与解决办法

V8最初为浏览器设计,遇到大内存使用的场景较少,在设计上默认对内存使用存在限制,只允许使用部分内存,64位系统可允许使用内存约1.4g,32位系统约0.7g。如下代码所示,在Node中查看所依赖的V8引擎的内存限制方法:

process.memoryUsage();

// 返回内存的使用量,单位字节
{
  rss: 22953984,
  // 申请的总的堆内存
  heapTotal: 9682944,
  // 已使用的堆内存
  heapUsed: 5290344,
  external: 9388
}

V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.

V8限制内存使用大小还有另一个重要原因,堆内存过大时V8执行垃圾回收的时间较久(1.5g50ms),做非增量式的垃圾回收要更久(1.5g1s)。在后续讲解了V8的垃圾回收机制后相信大家更能感同身受。

虽然V8引擎对内存使用做了限制,但是同样暴露修改内存限制的方法,就是启动V8引擎时添加相关参数,下面代码演示在Node中修改依赖的V8引擎内存限制:

# 更改老生代的内存限制,单位mb
node --max-old-space-size=2048 index.js

# 更改新生代的内存限制,单位mb
node --max-semi-space-size=1024=64 index.js

这里需要注意的是更改的新生代的内存的语法已经更改为上述的写法,且单位也由kb变成了mb,旧的写法是node --max-new-space-size,可以通过下面命令查询当前Node环境修改新生代内存的语法:

node --v8-options | grep max

V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.

V8垃圾回收策略

在引擎的垃圾自动回收机制的历史演变中,人们发现是没有一种通用的可以解决任何场景下垃圾回收的算法的。因此现代垃圾回收算法根据对象的存活时间将内存垃圾进行分代分代垃圾回收算法就是对不同类别的内存垃圾实行不同的回收算法。

V8将内存分为新生代老生代两种:

  • 新生代内存中的对象存活时间较短
  • 老生代内存中代对象存活时间较长或是常驻内存

新生代内存存放在新生代内存空间(semispace)中,老生代内存存放在老生代内存空间中(oldspace),如下图所示:

V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.

  • 新生代内存采用Scavenge算法
  • 老生代内存采用Mark-SweepMark-Compact算法

下面我们看看Scavenge的算法逻辑吧!

Scavenge算法

对于新生代内存的内存回收采用Scavenge算法,Scavenge的具体实现采用的是Cheney算法。Cheney算法是将新生代内存空间一分为二,一个空间处于使用状态(FromSpace),一个空间处于空闲状态(称为ToSpace

  • V8의 메모리 제한 및 해결 방법
  • Scavenge 알고리즘
  • 도달성 분석 알고리즘 논리 및 생존 개체 표시를 위한 최적화 방법을 기반으로 함
  • 차세대 메모리 개체 승격 조건,
  • Scavenge 알고리즘의 깊이/폭 우선 순위 차이
  • 세대 간 메모리 쓰기 장벽
  • 구세대 메모리 개체 표시 지우기/구성 알고리즘
  • li>
  • GCSTW 이유 및 최적화 전략

V8의 메모리 제한 및 솔루션

V8은 원래 브라우저용으로 설계되었습니다. 기본적으로 메모리 사용에 제한이 있는 설계는 일부입니다. 64비트 시스템에서는 약 1.4g, 32비트 시스템에서는 약 0.7g 정도의 메모리를 사용할 수 있습니다. 다음 코드와 같이 Node:

var temp2 = {
  ref: temp1,
}

var temp3 = {
  ref: temp1,
}

var temp1 = {}
V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.

🎜V8 메모리 사용량을 제한하는 또 다른 중요한 이유가 있습니다. 힙 메모리가 너무 큰 경우 V8 가비지 수집을 수행하는 데 시간이 오래 걸리고(1.5g 50ms 소요), 비증분 가비지 수집을 수행하는 데 더 오랜 시간이 걸립니다( 1.5g 1초가 소요됩니다). 나중에 V8의 가비지 수집 메커니즘을 설명하고 나면 모두가 더 공감할 수 있을 것이라고 믿습니다. 🎜🎜V8 엔진은 메모리 사용량에 제한이 있지만 메모리 제한을 수정하는 방법도 공개되어 있는데, 이는 V8 엔진을 시작할 때 관련 매개변수를 추가하는 것입니다. 다음 코드는 노드에서 종속 <code>V8 엔진 메모리 제한 수정에 설명되어 있습니다. 🎜
const temp1 = {}

const temp2 = {
  ref: temp1,
}
🎜 여기서 주목해야 할 점은 변경된 차세대 메모리의 구문이 변경되었다는 것입니다. 위에서 언급한 쓰기 방식으로 변경되었으며, 단위도 kb에서 mb로 변경되었습니다. 예전 쓰기 방식은 node --max-입니다. new-space-size. 다음 명령을 통해 현재 를 쿼리할 수 있습니다. Node 환경은 차세대 메모리의 구문을 수정합니다: 🎜rrreee🎜V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.🎜

V8 가비지 수집 전략

🎜엔진의 자동 가비지 수집 메커니즘이 역사적으로 발전하면서 사람들은 어떤 시나리오에서도 가비지 수집을 해결할 수 있는 일반적인 알고리즘이 없다는 사실을 발견했습니다. 따라서 최신 가비지 수집 알고리즘은 객체의 생존 시간에 따라 메모리 가비지를 세대로 나눕니다. 세대 가비지 수집 알고리즘은 다양한 범주의 메모리 가비지를 분류하는 것입니다. 알고리즘. 🎜🎜V8은 메모리를 신세대구세대의 두 가지 유형으로 나눕니다. 🎜
  • 신세대 메모리에 있는 객체는 살아남습니다. 시간은 더 짧아진다
  • 구세대 메모리의 세대 객체는 생존 시간이 길거나 메모리에 상주한다
🎜신세대 메모리는 신세대 메모리 공간에 저장된다 (semispace code>), Old Generation 메모리는 아래 그림과 같이 Old Generation 메모리 공간(<code>oldspace)에 저장됩니다. 🎜🎜🎜
  • 신세대 메모리는 Scavenge 알고리즘을 사용합니다. li>
  • 구세대 메모리는 Mark-SweepMark-Compact 알고리즘을 사용합니다
🎜 Scavengecode> 알고리즘 로직을 살펴보겠습니다! 🎜

Scavenge 알고리즘

🎜신세대 메모리의 메모리 재활용을 위해 Scavenge 알고리즘이 사용됩니다. >Scavenge의 특정 구현은 Cheney 알고리즘을 사용합니다. Cheney 알고리즘은 차세대 메모리 공간을 두 개로 나누어 한 공간은 사용 중(FromSpace)이고 다른 공간은 유휴 상태(ToSpace 코드>). 🎜🎜🎜🎜<p>在内存开始分配时,首先在<code>FromSpace中进行分配,垃圾回收机制执行时会检查FromSpace中的存活对象,存活对象会被会被复制到ToSpace,非存活对象所占用的空间将被释放,复制完成后FromSpaceToSpace的角色将翻转。当一个对象多次复制后依然处于存活状态,则认为其是长期存活对象,此时将发生晋升,然后该对象被移动到老生代空间oldSpace中,采用新的算法进行管理。

V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.

Scavenge算法其实就是在两个空间内来回复制存活对象,是典型的空间换时间做法,所以非常适合新生代内存,因为仅复制存活的对象且新生代内存中存活对象是占少数的。但是有如下几个重要问题需要考虑:

  • 引用避免重复拷贝

假设存在三个对象temp1、temp2、temp3,其中temp2、temp3都引用了temp1,js代码示例如下:

var temp2 = {
  ref: temp1,
}

var temp3 = {
  ref: temp1,
}

var temp1 = {}

FromSpace中拷贝temp2ToSpace中时,发现引用了temp1,便把temp1也拷贝到ToSpace,是一个递归的过程。但是在拷贝temp3时发现也引用了temp1,此时再把temp1拷贝过去则重复了。

要避免重复拷贝,做法是拷贝时给对象添加一个标记visited表示该节点已被访问过,后续通过visited属性判断是否拷贝对象。

  • 拷贝后保持正确的引用关系

还是上述引用关系,由于temp1不需要重复拷贝,temp3被拷贝到ToSpace之后不知道temp1对象在ToSpace中的内存地址。

做法是temp1被拷贝过去后该对象节点上会生成新的field属性指向新的内存空间地址,同时更新到旧内存对象的forwarding属性上,因此temp3就可以通过旧temp1forwarding属性找到在ToSpace中的引用地址了。

内存对象同时存在于新生代和老生代之后,也带来了问题:

  • 内存对象跨代(跨空间)后如何标记
const temp1 = {}

const temp2 = {
  ref: temp1,
}

比如上述代码中的两个对象temp1temp2都存在于新生代,其中temp2引用了temp1。假设在经过GC之后temp2晋升到了老生代,那么在下次GC的标记阶段,如何判断temp1是否是存活对象呢?

在基于可达性分析算法中要知道temp1是否存活,就必须要知道是否有根对象引用引用了temp1对象。如此的话,年轻代的GC就要遍历所有的老生代对象判断是否有根引用对象引用了temp1对象,如此的话分代算法就没有意义了。

解决版本就是维护一个记录所有的跨代引用的记录集,它是写缓冲区的一个列表。只要有老生代中的内存对象指向了新生代内存对象时,就将老生代中该对象的内存引用记录到记录集中。由于这种情况一般发生在对象写的操作,顾称此为写屏障,还一种可能的情况就是发生在晋升时。记录集的维护只要关心对象的写操作和晋升操作即可。此是又带来了另一个问题:

  • 每次写操作时维护记录集的额外开销

优化的手段是在一些Crankshaft操作中是不需要写屏障的,还有就是栈上内存对象的写操作是不需要写屏障的。还有一些,更多的手段就不在这里过多讨论。

  • 缓解Scavenge算法内存利用率不高问题

新生代内存中存活对象占比是相对较小的,因此可以在分配空间时,ToSpace可以分配的小一些。做法是将ToSpace空间分成S0S1两部分,S0用作于ToSpaceS1与原FromSpace合并当成FromSpace

V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.

Scavenge算法中深度/广度优先的区别

垃圾回收算法中,识别内存对象是否是垃圾的机制一般有两种:引用计数基于可达性分析

접근성 분석을 기반으로 모든 루트 참조(예: 전역 변수 등)를 찾고, 모든 루트 참조를 순회하며, 순회된 모든 개체는 라이브 개체로 표시됩니다. 이때 공간에 있는 다른 메모리 개체는 죽은 개체이므로 유향 그래프를 구성합니다.

재귀의 한계를 고려하여 재귀 논리는 일반적으로 비재귀 구현을 사용하여 구현됩니다. 일반적으로 사용되는 알고리즘에는 너비 우선 알고리즘과 깊이 우선 알고리즘이 있습니다. 둘 사이의 차이점은 다음과 같습니다.

  • ToSpace에 깊이 우선 복사하면 메모리 개체의 순서가 변경되어 참조 관계가 있는 개체가 서로 더 가까워집니다. 그 이유는 자신을 복사한 후 자신이 참조하는 객체가 직접 복사되기 때문에 ToSpace에서 관련 객체가 더 가까워지기 때문입니다.
  • ToSpace时改变了内存对象的排列顺序,使得有引用关系的对象距离较近。原因是拷贝完自己之后直接拷贝自己引用的对象,因此相关的对象便在ToSpace中靠的较近
  • 深度优先正好相反

因为CPU的缓存策略,会在读取内存对象时有很大概率把他后面的对象一起读,目的是为了更快的命中缓存。因为在代码开发期间很常见的场景就是obj1.obj2.obj3,此时CPU读取obj1时如果把后面的obj2obj3一起读的话,则很利于命中缓存。

所以深度优先的算法更利于业务逻辑命中缓存,但是其实现需要依赖额外的栈辅助实现算法,对内存空间有消耗。广度优先则相反,无法提升缓存命中,但是其实现可以利用指针巧妙的避开空间消耗,算法的执行效率高。

新生代内存对象的晋升条件

新生代中的内存对象如果想晋升到老生代需要满足如下几个条件:

  • 对象是否经历过Scavenge回收
  • ToSpace的内存使用占比不能超过限制

判断是否经历过Scavenge的GC的逻辑是,每次GC时给存活对象的age属性+1,当再次GC的时候判断age属性即可。基本的晋升示意图如下所示:

V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.

老生代内存中,长期存活的对象较多,无法采取Scavenge算法回收的原因在于:

  • 存活对象较多导致复制效率低下
  • 浪费了一半的内存空间

老生代内存对象的回收算法

老生代内存空间的垃圾回收采用的是标记清除Mark-Sweep)和标记整理Mark-Compact)结合的方式。标记清除分为两部分:

  • 标记阶段
  • 清除阶段(如果是标记整理则是整理阶段)

在标记阶段遍历老生代堆内存中的所有内存对象,并对活着的对象做标记,清除阶段只清理未被标记的对象。原因是:老生代内存中非存活对象占少数。

V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.

如上图所示,标记清除存在的一个问题是清理之后存在了不连续的空间导致无法继续利用,所以对于老生代内存空间的内存清理需要结合标记整理的方案。该方案是在标记过程中将活着的对象往一侧移动,移动完成后再清理界外的所有非存活对象移除。

V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.

垃圾回收的全暂停

垃圾回收时需要暂停应用执行逻辑,待垃圾回收机制结束后再恢复应用执行逻辑,该行为称为“全暂停”,也就是常说的Stop The World,简称STW。对新生代内存的垃圾回收该行为对应用执行影响不大,但是老生代内存由于存活对象较多,所以老生代内存的垃圾回收造成的全停顿影响非常大。

V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.

V8为了优化GC的全暂停时间,还引入了增量标记并发标记并行标记增量整理并行清理延迟清理等方式。

STW优化

衡量垃圾回收所用时间的一个重要指标是执行 GCDepth 우선순위는 정반대

CPU의 캐싱 전략으로 인해 메모리 개체를 읽을 때 캐시에 더 빨리 도달하기 위해 뒤에 있는 개체를 함께 읽을 가능성이 높습니다. 코드 개발 중 매우 일반적인 시나리오는 obj1.obj2.obj3이기 때문에 이때 CPU가 obj1을 읽을 때 다음 obj2가 , obj3 을 함께 읽으면 캐시를 hit하는 것이 매우 도움이 될 것입니다. 🎜🎜그래서 깊이 우선 알고리즘은 비즈니스 로직이 캐시에 도달하는 데 더 도움이 되지만 이를 구현하려면 메모리 공간을 소비하는 추가적인 스택 지원 알고리즘 구현이 필요합니다. 반대로 너비 우선은 캐시 적중률을 향상시킬 수 없지만 포인터를 사용하여 공간 소비를 교묘하게 피할 수 있으며 알고리즘 실행 효율성이 높습니다. 🎜

🎜신세대 메모리 객체의 승격 조건🎜

🎜신세대의 메모리 객체가 Old Generation으로 승격되려면 다음 조건을 충족해야 합니다. : 🎜🎜🎜개체 Scavenge 재활용 여부🎜ToSpace의 메모리 사용량 비율은 제한을 초과할 수 없습니다🎜결정 Scavenge가 발생했는지 여부 GC의 논리는 GC 때마다 살아남은 개체의 <code>age 속성에 +1을 제공하는 것입니다. code>.GC가 다시 완료되면 age 속성을 ​​판단하면 됩니다. 기본 프로모션 다이어그램은 다음과 같습니다. 🎜🎜7 .png🎜🎜구세대 메모리에는 장기간 생존하는 객체가 많습니다. Scavenge 알고리즘을 재활용할 수 없는 이유는 다음과 같습니다. 🎜🎜🎜생존 객체의 수가 많기 때문에 복사 효율성 저하 🎜메모리 공간의 절반 낭비

🎜구세대 메모리 개체의 재활용 알고리즘🎜

🎜쓰레기 구세대 메모리 공간 모음이 사용됩니다. Mark Sweep(Mark-Sweep)과 Mark Compact(Mark- 컴팩트). 마킹과 클리어링은 두 부분으로 나뉩니다: 🎜🎜🎜마킹 단계🎜클리어링 단계(마킹과 정렬인 경우 정렬 단계)🎜마킹 단계에서 모든 메모리를 탐색합니다. 마킹 단계 중 구세대 힙 메모리 개체 및 라이브 개체 표시 정리 단계에서는 표시되지 않은 개체만 정리합니다. 그 이유는 비생존 개체가 Old Generation 메모리에서 소수를 차지하기 때문입니다. 🎜🎜V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.🎜🎜As 위 그림에서 볼 수 있듯이 마크 클리어의 한 가지 문제점은 클리어 후 더 이상 사용할 수 없는 불연속적인 공간이 있다는 것입니다. 따라서 구세대 메모리 공간의 메모리 정리는 마크 정렬 솔루션과 결합되어야 합니다. 이 솔루션은 마킹 과정에서 생물체를 한쪽으로 이동시킨 후, 이동이 완료된 후 경계 밖의 모든 무생물체를 정리하고 제거하는 것입니다. 🎜🎜V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.🎜

🎜가비지 수집을 위한 전체 일시 중지🎜

🎜가비지 수집 중에는 애플리케이션 실행 로직을 일시 중지해야 하며, 가비지 수집 메커니즘이 완료된 후 애플리케이션 실행 로직을 재개할 수 있습니다. 이 동작을 "🎜full Pause🎜"라고 하며 Stop The World 또는 줄여서 STW라고도 합니다. Young Generation 메모리의 가비지 컬렉션은 애플리케이션 실행에 거의 영향을 미치지 않지만, Old Generation 메모리에는 살아남은 개체가 많기 때문에 Old Generation 메모리의 가비지 컬렉션으로 인한 전체 일시 중지의 영향은 매우 큽니다. 🎜🎜V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.🎜🎜V8 GC의 전체 일시정지 시간을 최적화하기 위해 incremental mark, concurrency mark, parallel mark, incrementalfinishing, 병렬 정리, 지연 정리 등도 도입되었습니다. 🎜

🎜STW 최적화🎜

🎜가비지 수집에 소요된 시간을 측정하는 중요한 측정항목은 GC. STW의 영향은 용납할 수 없기 때문에 V8도 많은 최적화 방법을 채택했습니다. 🎜<ul><li>병렬 GC</li></ul> <p> GC 프로세스에서는 많은 작업을 수행해야 하므로 메인 스레드에서 STW 현상이 발생합니다. 병렬 GC의 방법은 여러 개의 보조 스레드를 열어 GC 작업을 공유하는 것입니다. 이 접근 방식은 여전히 ​​STW 현상을 피할 수는 없지만 활성화된 보조 스레드 수에 따라 STW의 총 시간을 줄일 수 있습니다. </p> <p><img src="https://img.php.cn/upload/image/795/713/176/165106317370481V8%EC%9D%98%20%EB%A9%94%EB%AA%A8%EB%A6%AC%20%EA%B4%80%EB%A6%AC%EC%99%80%20%EA%B0%80%EB%B9%84%EC%A7%80%20%EC%88%98%EC%A7%91%20%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%90%20%EB%8C%80%ED%95%B4%20%EC%9D%B4%EC%95%BC%EA%B8%B0%ED%95%B4%20%EB%B3%B4%EA%B2%A0%EC%8A%B5%EB%8B%88%EB%8B%A4." title="165106317370481V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다." alt="1V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다."></p> <ul><li>Incremental<code>GCGC

增量GC将GC工作进行拆分,并在主线程中间歇的分步执行。该做法并不会减少GC的时间,相反会稍微花销,但是它同样会减少GC的STW的总时间。

1V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.

  • 并发GC

并发GC是指GC在后台运行,不再在主线程运行。该做法会避免STW现象。

1V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.

  • 空闲时间GC

Chrome中动画的渲染大约是60帧(每帧约16ms),如果当前渲染所花费时间每达到16.6ms,此时则有空闲时间做其他事情,比如部分GC任务。

1V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.

减少垃圾回收的影响

想要提高执行效率要尽量减少垃圾回收的执行和消耗:

  • 慎把内存当作缓存,小心把对象当作缓存,要合理限制过期时间和无限增长的问题,可以采用lru策略

  • Node

      Incremental GC는 GC 작업을 분할하여 간헐적으로 메인 스레드에서 실행합니다. 이 접근 방식은 GC 시간을 줄이지 않습니다. 반대로 비용은 약간 들지만 GC의 총 STW 시간도 줄입니다.
    • 1V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.
    동시 GC

동시 GC는 GC가 백그라운드에서 실행되고 더 이상 메인 스레드에서 실행되지 않음을 의미합니다. 이 접근 방식은 STW 현상을 방지합니다. 1V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.

🎜🎜 유휴 시간 GC🎜🎜🎜 Chrome에서 애니메이션 렌더링은 약 60 프레임입니다(각 프레임은 약 16ms). >), 현재 렌더링 시간이 16.6ms에 도달하면 일부 GC 작업 등 다른 작업을 할 수 있는 여유 시간이 생깁니다. 🎜🎜1V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.🎜

가비지 수집의 영향 줄이기

🎜실행 효율성을 높이려면 가비지 수집의 실행과 소비를 최소화해야 합니다. 🎜🎜🎜 🎜메모리 사용 시 주의하세요. 캐시의 경우 객체를 캐시로 취급하는 데 주의하세요. 만료 시간과 무한 성장 문제를 합리적으로 제한하려면 lru 전략🎜🎜🎜🎜Node을 사용하여 메모리 사용을 피할 수 있습니다. 그렇지 않으면 메모리에 저장됩니다. 사용자 세션 개체가 많으면 이전 세대 메모리가 증가하여 정리 성능에 영향을 미치고 애플리케이션 실행 성능과 메모리 오버플로에도 영향을 미칩니다. Redis 등의 사용 방법이 개선되었습니다. 캐시를 외부로 이동할 때의 이점: 🎜🎜🎜상주 메모리 개체 수를 줄이고 가비지 수집을 더욱 효율적으로 만듭니다. 🎜🎜캐시는 프로세스 간에 공유할 수 있습니다. 🎜🎜🎜🎜🎜노드 관련 지식을 더 보려면 다음을 방문하세요. 🎜nodejs 튜토리얼 🎜! 🎜

위 내용은 V8의 메모리 관리와 가비지 수집 알고리즘에 대해 이야기해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제