


Lassen Sie uns über den Speicherverwaltungs- und Garbage-Collection-Algorithmus von V8 sprechen
Dieser Artikel wird Ihnen helfen, den Speicherverwaltungs- und Garbage-Collection-Algorithmus der V8-Engine zu verstehen. Ich hoffe, er wird Ihnen helfen!
Wie wir alle wissen, verwaltet JS automatisch die Speicherbereinigung, und Entwickler müssen sich nicht um die Speicherzuweisung und das Recycling kümmern. Darüber hinaus ist der Garbage-Collection-Mechanismus auch ein häufig getesteter Teil in Front-End-Interviews. Dieser Artikel erklärt hauptsächlich den Generations-Garbage-Collection-Algorithmus von V8. Ich hoffe, dass Freunde nach der Lektüre dieses Artikels ein schmerzhaftes
über den V8
-Garbage-Collection-Mechanismus haben können (haha, das ist es). schmerzhaft). ! ), behandelt der Artikel hauptsächlich den folgenden Inhalt: <code>V8
垃圾回收机制有个痛彻
(哈哈,是痛彻
!!!)的了解,文章主要涵盖如下内容:
-
V8
的内存限制与解决办法 - 新生代内存对象的
Scavenge
算法 - 基于
可达性分析算法
标记存活对象的逻辑以及优化手段 - 新生代内存对象的晋升条件、
-
Scavenge
算法的深度/广度优先区别 - 跨代内存的的写屏障
- 老生代内存对象的标记清除/整理算法
-
GC
的STW
原因及优化策略
V8的内存限制与解决办法
V8最初为浏览器设计,遇到大内存使用的场景较少,在设计上默认对内存使用存在限制,只允许使用部分内存,64位系统可允许使用内存约1.4g,32位系统约0.7g。如下代码所示,在Node中查看所依赖的V8引擎的内存限制方法:
process.memoryUsage(); // 返回内存的使用量,单位字节 { rss: 22953984, // 申请的总的堆内存 heapTotal: 9682944, // 已使用的堆内存 heapUsed: 5290344, external: 9388 }
V8
限制内存使用大小还有另一个重要原因,堆内存过大时V8
执行垃圾回收的时间较久(1.5g
要50ms
),做非增量式的垃圾回收要更久(1.5g
要1s
)。在后续讲解了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
将内存分为新生代
和老生代
两种:
- 新生代内存中的对象存活时间较短
- 老生代内存中代对象存活时间较长或是常驻内存
新生代内存存放在新生代内存空间(semispace
)中,老生代内存存放在老生代内存空间中(oldspace
),如下图所示:
- 新生代内存采用
Scavenge
算法 - 老生代内存采用
Mark-Sweep
和Mark-Compact
算法
下面我们看看Scavenge
的算法逻辑吧!
Scavenge算法
对于新生代内存的内存回收采用Scavenge
算法,Scavenge
的具体实现采用的是Cheney
算法。Cheney
算法是将新生代内存空间一分为二,一个空间处于使用状态(FromSpace
),一个空间处于空闲状态(称为ToSpace
V8
s Speicherbeschränkungen und Lösungen- -Algorithmus
- basierend auf der
Erreichbarkeitsanalysealgorithmus
-Logik und Optimierungsmethoden zum Markieren überlebender Objekte - Speicherobjekte der neuen Generation Promotion-Bedingungen,
Scavenge
Tiefe/Breite-Prioritätsunterschied des Algorithmus- Generationsübergreifende Speicher-Schreibbarriere
- Speicherobjekte der alten Generation markieren Lösch-/Organisationsalgorithmus li>
GC
sSTW
-Gründe und Optimierungsstrategien
Speicherbeschränkungen und Lösungen von V8
V8 wurde ursprünglich für Browser entwickelt. Es gibt weniger Szenarien, in denen großer Speicher verwendet wird. Im Design ist nur ein Teil des Speichers zulässig Das 64-Bit-System ermöglicht etwa 1,4 g Speicher und das 32-Bit-System etwa 0,7 g. Überprüfen Sie, wie im folgenden Code gezeigt, die Speicherbegrenzungsmethode der abhängigen V8-Engine im Knoten:var temp2 = { ref: temp1, } var temp3 = { ref: temp1, } var temp1 = {}
V8
Es gibt einen weiteren wichtigen Grund für die Begrenzung der Speichernutzung. Wenn der Heap-Speicher zu groß ist, V8 </code >Es dauert lange, die Garbage Collection durchzuführen (<code>1,5g
dauert 50ms
), und es dauert noch länger, eine nicht inkrementelle Garbage Collection durchzuführen ( 1,5g
Es dauert 1s
). Nachdem ich später den Garbage-Collection-Mechanismus von V8
erklärt habe, glaube ich, dass sich jeder besser damit identifizieren kann. 🎜🎜Obwohl die V8
-Engine die Speichernutzung begrenzt, wird auch die Methode zum Ändern der Speicherbegrenzung offengelegt, nämlich das Hinzufügen relevanter Parameter beim Starten der V8
-Engine Der folgende Code wird in Ändern des abhängigen Speicherlimits der <code>V8
-Engine im Knoten demonstriert: 🎜const temp1 = {} const temp2 = { ref: temp1, }
kb
zu mb
geändert. Die alte Schreibweise ist node --max-. new-space-size
Sie können den aktuellen über den folgenden Befehl abfragen. Node
ändert die Syntax des Speichers der neuen Generation: 🎜rrreee🎜V8-Garbage-Collection-Strategie
🎜Die historische Entwicklung des automatischen Garbage-Collection-Mechanismus der Engine hat gezeigt, dass es keinen allgemeinen Algorithmus gibt, der die Garbage-Collection in jedem Szenario lösen kann. Daher unterteilen moderne Garbage-Collection-Algorithmen den Speichermüll in Generationen entsprechend der Überlebenszeit von Objekten. Der Generational-Garbage-Collection-Algorithmus besteht darin, verschiedene Kategorien von Speichermüll zu klassifizieren Algorithmen. 🎜🎜V8
unterteilt den Speicher in zwei Typen: Neue Generation
und Alte Generation
: 🎜- Objekte im Speicher der neuen Generation bleiben bestehen Die Zeit ist kürzer
- Die Generationsobjekte im Speicher der alten Generation haben eine längere Überlebenszeit oder sind im Speicher resident
semispace</li></ul> code>), der Speicher der alten Generation wird im Speicherraum der alten Generation (<code>oldspace
) gespeichert, wie in der folgenden Abbildung dargestellt: 🎜🎜< img src="https://img.php.cn/upload/ image/871/474/429/165106312781601Lassen Sie uns über den Speicherverwaltungs- und Garbage-Collection-Algorithmus von V8 sprechen" title="165106312781601Lassen Sie uns über den Speicherverwaltungs- und Garbage-Collection-Algorithmus von V8 sprechen" alt="Lassen Sie uns über den Speicherverwaltungs- und Garbage-Collection-Algorithmus von V8 sprechen"/>🎜- Der Speicher der neuen Generation verwendet den
Scavenge
-Algorithmus li> - Der Speicher der alten Generation verwendet die Algorithmen
Mark-Sweep
undMark-Compact
Scavenge</code code>-Algorithmus! 🎜<h3 id="strong-Scavenge-Algorithmus-strong"><strong>Scavenge-Algorithmus</strong></h3>🎜Für das Speicherrecycling von Speicher der neuen Generation wird der <code>Scavenge
-Algorithmus verwendet, Scavenge< Die spezifische Implementierung von /code> verwendet den <code>Cheney
-Algorithmus. Der Cheney
-Algorithmus teilt den Speicherplatz der neuen Generation in zwei Bereiche auf, ein Speicherplatz wird verwendet (FromSpace
) und der andere befindet sich in einem Leerlaufzustand (genannt ToSpace<). /code> code>). 🎜🎜🎜🎜<p>在内存开始分配时,首先在<code>FromSpace
中进行分配,垃圾回收机制执行时会检查FromSpace
中的存活对象,存活对象会被会被复制到ToSpace
,非存活对象所占用的空间将被释放,复制完成后FromSpace
和ToSpace
的角色将翻转。当一个对象多次复制后依然处于存活状态,则认为其是长期存活对象,此时将发生晋升,然后该对象被移动到老生代空间oldSpace
中,采用新的算法进行管理。Scavenge
算法其实就是在两个空间内来回复制存活对象,是典型的空间换时间做法,所以非常适合新生代内存,因为仅复制存活的对象且新生代内存中存活对象是占少数的。但是有如下几个重要问题需要考虑:
- 引用避免重复拷贝
假设存在三个对象temp1、temp2、temp3
,其中temp2、temp3
都引用了temp1
,js代码示例如下:
var temp2 = { ref: temp1, } var temp3 = { ref: temp1, } var temp1 = {}
从FromSpace
中拷贝temp2
到ToSpace
中时,发现引用了temp1
,便把temp1
也拷贝到ToSpace
,是一个递归的过程。但是在拷贝temp3
时发现也引用了temp1
,此时再把temp1
拷贝过去则重复了。
要避免重复拷贝,做法是拷贝时给对象添加一个标记visited
表示该节点已被访问过,后续通过visited
属性判断是否拷贝对象。
- 拷贝后保持正确的引用关系
还是上述引用关系,由于temp1
不需要重复拷贝,temp3
被拷贝到ToSpace
之后不知道temp1
对象在ToSpace
中的内存地址。
做法是temp1
被拷贝过去后该对象节点上会生成新的field
属性指向新的内存空间地址,同时更新到旧内存对象的forwarding
属性上,因此temp3
就可以通过旧temp1
的forwarding
属性找到在ToSpace
中的引用地址了。
内存对象同时存在于新生代和老生代之后,也带来了问题:
- 内存对象跨代(跨空间)后如何标记
const temp1 = {} const temp2 = { ref: temp1, }
比如上述代码中的两个对象temp1
和temp2
都存在于新生代,其中temp2
引用了temp1
。假设在经过GC
之后temp2
晋升到了老生代,那么在下次GC
的标记阶段,如何判断temp1
是否是存活对象呢?
在基于可达性分析算法中要知道temp1
是否存活,就必须要知道是否有根对象引用
引用了temp1
对象。如此的话,年轻代的GC
就要遍历所有的老生代对象判断是否有根引用对象引用了temp1
对象,如此的话分代算法就没有意义了。
解决版本就是维护一个记录所有的跨代引用的记录集,它是写缓冲区
的一个列表。只要有老生代中的内存对象指向了新生代内存对象时,就将老生代中该对象的内存引用记录到记录集中。由于这种情况一般发生在对象写的操作,顾称此为写屏障,还一种可能的情况就是发生在晋升时。记录集的维护只要关心对象的写操作和晋升操作即可。此是又带来了另一个问题:
- 每次写操作时维护记录集的额外开销
优化的手段是在一些Crankshaft
操作中是不需要写屏障的,还有就是栈上内存对象的写操作是不需要写屏障的。还有一些,更多的手段就不在这里过多讨论。
- 缓解
Scavenge
算法内存利用率不高问题
新生代内存中存活对象占比是相对较小的,因此可以在分配空间时,ToSpace
可以分配的小一些。做法是将ToSpace
空间分成S0
和S1
两部分,S0
用作于ToSpace
,S1
与原FromSpace
合并当成FromSpace
。
Scavenge算法中深度/广度优先的区别
垃圾回收算法中,识别内存对象是否是垃圾的机制一般有两种:引用计数和基于可达性分析。
Basierend auf der Erreichbarkeitsanalyse geht es darum, alle Stammreferenzen (z. B. globale Variablen usw.) zu finden, alle Stammreferenzen zu durchlaufen und alle Referenzen auf der rekursiven Stammreferenz zu durchlaufen. Alle durchquerten Objekte sind Live-Objekte und markiert. Zu diesem Zeitpunkt sind andere Speicherobjekte im Raum „tote Objekte“ und bilden somit einen „gerichteten Graphen“. Angesichts der Einschränkung der Rekursion wird rekursive Logik im Allgemeinen mithilfe einer nicht-rekursiven Implementierung implementiert. Zu den häufig verwendeten Algorithmen gehören Breiten- und Tiefenalgorithmen. Der Unterschied zwischen den beiden ist:
Beim Tiefenkopieren nach ToSpace
ändert sich die Reihenfolge der Speicherobjekte, wodurch Objekte mit Referenzbeziehungen näher beieinander liegen. Der Grund dafür ist, dass nach dem Kopieren das von ihm selbst referenzierte Objekt direkt kopiert wird, sodass die zugehörigen Objekte in ToSpace
näher beieinander liegen. Die Tiefenpriorität ist genau das Gegenteil
obj1.obj2
. Zu diesem Zeitpunkt liest die CPU obj1
, wenn der folgende obj2
, Wenn obj3
zusammen gelesen wird, ist es sehr hilfreich, auf den Cache zuzugreifen. - Der Tiefenalgorithmus ist also förderlicher für die Geschäftslogik, die auf den Cache trifft, aber seine Implementierung erfordert eine zusätzliche stapelunterstützte Implementierung des Algorithmus, die Speicherplatz verbraucht. Im Gegensatz dazu kann „Breadth First“ die Cache-Treffer nicht verbessern, aber seine Implementierung kann Zeiger verwenden, um den Speicherplatzverbrauch geschickt zu vermeiden, und die Effizienz der Algorithmusausführung ist hoch.
ToSpace
时改变了内存对象的排列顺序,使得有引用关系的对象距离较近。原因是拷贝完自己之后直接拷贝自己引用的对象,因此相关的对象便在ToSpace
中靠的较近 - 深度优先正好相反
因为CPU的缓存策略,会在读取内存对象时有很大概率把他后面的对象一起读,目的是为了更快的命中缓存。因为在代码开发期间很常见的场景就是obj1.obj2.obj3
,此时CPU读取obj1
时如果把后面的obj2
、obj3
一起读的话,则很利于命中缓存。
所以深度优先的算法更利于业务逻辑命中缓存,但是其实现需要依赖额外的栈辅助实现算法,对内存空间有消耗。广度优先则相反,无法提升缓存命中,但是其实现可以利用指针巧妙的避开空间消耗,算法的执行效率高。
新生代内存对象的晋升条件
新生代中的内存对象如果想晋升到老生代需要满足如下几个条件:
- 对象是否经历过
Scavenge
回收 -
ToSpace
的内存使用占比不能超过限制
判断是否经历过Scavenge
的GC的逻辑是,每次GC
时给存活对象的age
属性+1
,当再次GC
的时候判断age
属性即可。基本的晋升示意图如下所示:
老生代内存中,长期存活的对象较多,无法采取Scavenge
算法回收的原因在于:
- 存活对象较多导致复制效率低下
- 浪费了一半的内存空间
老生代内存对象的回收算法
老生代内存空间的垃圾回收采用的是标记清除
(Mark-Sweep
)和标记整理
(Mark-Compact
)结合的方式。标记清除分为两部分:
- 标记阶段
- 清除阶段(如果是标记整理则是整理阶段)
在标记阶段遍历老生代堆内存中的所有内存对象,并对活着的对象做标记,清除阶段只清理未被标记的对象。原因是:老生代内存中非存活对象占少数。
如上图所示,标记清除存在的一个问题是清理之后存在了不连续的空间导致无法继续利用,所以对于老生代内存空间的内存清理需要结合标记整理的方案。该方案是在标记过程中将活着的对象往一侧移动,移动完成后再清理界外的所有非存活对象移除。
垃圾回收的全暂停
垃圾回收时需要暂停应用执行逻辑,待垃圾回收机制结束后再恢复应用执行逻辑,该行为称为“全暂停”,也就是常说的Stop The World
,简称STW
。对新生代内存的垃圾回收该行为对应用执行影响不大,但是老生代内存由于存活对象较多,所以老生代内存的垃圾回收造成的全停顿影响非常大。
V8为了优化GC的全暂停时间,还引入了增量标记
、并发标记
、并行标记
、增量整理
、并行清理
、延迟清理
等方式。
STW优化
衡量垃圾回收所用时间的一个重要指标是执行 GC
Beförderungsbedingungen für Speicherobjekte der neuen Generation🎜
🎜Wenn Speicherobjekte der neuen Generation zur alten Generation befördert werden möchten, müssen sie die folgenden Bedingungen erfüllen : 🎜🎜🎜Objekte Ob es einScavenge
-Recycling erfahren hat🎜Das Speichernutzungsverhältnis von ToSpace
darf den Grenzwert nicht überschreiten🎜Bestimmen ob es Scavenge
erfahren hat. Die Logik von GC besteht darin, dem age
-Attribut des überlebenden Objekts jedes Mal +1
zu geben GC code>, und wenn <code>GC erneut durchgeführt wird
, beurteilen Sie einfach das Attribut age
. Das grundlegende Werbediagramm sieht wie folgt aus: 🎜🎜Scavenge
-Algorithmus nicht recycelt werden kann, ist: 🎜🎜🎜Die große Anzahl überlebender Objekte führt dazu Geringe Kopiereffizienz 🎜Die Hälfte des Speicherplatzes wurde verschwendet🎜Der Recycling-Algorithmus von Speicherobjekten der alten Generation🎜
🎜 Die Garbage Collection des Speicherplatzes der alten Generation wird übernommen. Es handelt sich um eine Kombination ausMark Sweep
(Mark-Sweep
) und Mark Compact
( Mark-Compact
). Das Markieren und Löschen ist in zwei Teile unterteilt: 🎜🎜🎜Markierungsphase🎜Löschphase (wenn es sich um Markieren und Sortieren handelt, handelt es sich um die Sortierphase)🎜Durchlaufen des gesamten Speichers im Heap-Speicher der alten Generation während der Markierungsphase. Objekte markieren und Live-Objekte markieren. In der Bereinigungsphase werden nur nicht markierte Objekte bereinigt. Der Grund dafür ist: Nicht überlebende Objekte machen im Gedächtnis der alten Generation eine Minderheit aus. 🎜🎜🎜Vollständige Pause für die Garbage Collection🎜
🎜Die Anwendungsausführungslogik muss während der Garbage Collection angehalten werden, und die Anwendungsausführungslogik kann nach Abschluss des Garbage Collection-Mechanismus wieder aufgenommen werden. Dieses Verhalten wird „🎜volle Pause🎜“ genannt, auch bekannt alsStop The World
, oder kurz STW
. Die Garbage Collection des Speichers der jungen Generation hat kaum Auswirkungen auf die Anwendungsausführung. Da es jedoch viele überlebende Objekte im Speicher der alten Generation gibt, ist die Auswirkung vollständiger Pausen, die durch die Garbage Collection des Speichers der alten Generation verursacht werden, sehr groß. 🎜🎜Inkrementelle Markierung
, Parallelitätsmarkierung
, Parallelmarkierung
, Inkrementelle Endbearbeitung
werden ebenfalls eingeführt. code>, Parallel Cleanup
, Delayed Cleanup
usw. 🎜🎜STW-Optimierung🎜
🎜Eine wichtige Metrik zur Messung der für die Garbage Collection aufgewendeten Zeit ist die Zeitspanne, die der Hauptthread beim Ausführen vonGC. Die Auswirkungen von STW sind inakzeptabel, daher hat V8 auch viele Optimierungsmethoden übernommen. 🎜<ul><li>Paralleler GC</li></ul>
<p>Der GC-Prozess muss viele Dinge tun, was zum STW-Phänomen im Hauptthread führt. Die Methode des parallelen GC besteht darin, mehrere Hilfsthreads zu öffnen, um die GC-Arbeit zu teilen. Dieser Ansatz kann das STW-Phänomen immer noch nicht vermeiden, kann jedoch die Gesamtzeit von STW reduzieren, abhängig von der Anzahl der aktivierten Hilfsthreads. </p>
<p><img src="https://img.php.cn/upload/image/795/713/176/165106317370481Lassen%20Sie%20uns%20%C3%BCber%20den%20Speicherverwaltungs-%20und%20Garbage-Collection-Algorithmus%20von%20V8%20sprechen" title="165106317370481Lassen Sie uns über den Speicherverwaltungs- und Garbage-Collection-Algorithmus von V8 sprechen" alt="1Lassen Sie uns über den Speicherverwaltungs- und Garbage-Collection-Algorithmus von V8 sprechen"></p>
<ul><li>Inkrementeller<code>GC
GC
增量GC将GC工作进行拆分,并在主线程中间歇的分步执行。该做法并不会减少GC的时间,相反会稍微花销,但是它同样会减少GC的STW的总时间。
- 并发
GC
并发GC是指GC在后台运行,不再在主线程运行。该做法会避免STW现象。
- 空闲时间
GC
Chrome
中动画的渲染大约是60
帧(每帧约16ms
),如果当前渲染所花费时间每达到16.6ms
,此时则有空闲时间做其他事情,比如部分GC
任务。
减少垃圾回收的影响
想要提高执行效率要尽量减少垃圾回收的执行和消耗:
慎把内存当作缓存,小心把对象当作缓存,要合理限制过期时间和无限增长的问题,可以采用lru策略
-
Node
- Inkrementeller GC teilt die GC-Arbeit auf und führt sie zeitweise im Hauptthread aus. Dieser Ansatz wird die GC-Zeit nicht verkürzen, im Gegenteil, er wird ein wenig kosten, aber er wird auch die gesamte STW-Zeit des GC verkürzen.
-
GC
-
Concurrent GC bedeutet, dass GC im Hintergrund und nicht mehr im Hauptthread ausgeführt wird. Dieser Ansatz vermeidet das STW-Phänomen.
GC
🎜🎜🎜Das Rendern von Animationen in Chrome
beträgt etwa 60
Frames (jeder Frame dauert etwa 16 ms
). >), Wenn die aktuelle Renderzeit 16,6 ms
erreicht, bleibt freie Zeit für andere Dinge, wie zum Beispiel einige GC
-Aufgaben. 🎜🎜Reduzieren Sie die Auswirkungen der Garbage Collection
🎜Wenn Sie die Ausführungseffizienz verbessern möchten, müssen Sie die Ausführung und den Verbrauch der Garbage Collection minimieren: 🎜🎜🎜 🎜Seien Sie vorsichtig, wenn Sie Speicher verwenden. Achten Sie beim Caching darauf, Objekte als Cache zu behandeln. Um die Ablaufzeit und unendliche Wachstumsprobleme angemessen zu begrenzen, können Sie die LRU-Strategie verwenden, um die Verwendung von Speicher zu vermeiden zum Speichern von Benutzersitzungen, andernfalls werden sie im Speicher gespeichert. Eine große Anzahl von Benutzersitzungsobjekten führt zu einer Vergrößerung des Speichers der alten Generation, was sich auf die Bereinigungsleistung und dann auf die Anwendungsausführungsleistung und den Speicherüberlauf auswirkt. Verbesserte Möglichkeiten zur Verwendung von Redis usw. Vorteile der Verlagerung des Caches nach außen: 🎜🎜🎜 Reduzieren Sie die Anzahl residenter Speicherobjekte und machen Sie die Speicherbereinigung effizienter. 🎜🎜 Der Cache kann zwischen Prozessen gemeinsam genutzt werden. 🎜🎜🎜🎜🎜 Weitere knotenbezogene Kenntnisse finden Sie unter: 🎜 NodeJS-Tutorial🎜! 🎜Das obige ist der detaillierte Inhalt vonLassen Sie uns über den Speicherverwaltungs- und Garbage-Collection-Algorithmus von V8 sprechen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



So löschen Sie einen Knoten mit nvm: 1. Laden Sie „nvm-setup.zip“ herunter und installieren Sie es auf dem Laufwerk C. 2. Konfigurieren Sie Umgebungsvariablen und überprüfen Sie die Versionsnummer mit dem Befehl „nvm -v“. install“-Befehl Knoten installieren; 4. Löschen Sie den installierten Knoten über den Befehl „nvm uninstall“.

Wie gehe ich mit dem Datei-Upload um? Der folgende Artikel stellt Ihnen vor, wie Sie Express zum Hochladen von Dateien im Knotenprojekt verwenden. Ich hoffe, er ist hilfreich für Sie!

Während dieser Zeit habe ich einen dynamischen HTML-Dienst entwickelt, der allen Kategorien von Tencent-Dokumenten gemeinsam ist. Um die Generierung und Bereitstellung des Zugriffs auf verschiedene Kategorien zu erleichtern und dem Trend der Cloud-Migration zu folgen, habe ich über die Verwendung von Docker nachgedacht Serviceinhalte verwalten und Produktversionen einheitlich verwalten. In diesem Artikel werden die Optimierungserfahrungen, die ich bei der Bereitstellung von Docker gesammelt habe, als Referenz weitergegeben.

In diesem Artikel stellen wir Ihnen das Prozessmanagement-Tool „pm2“ von Node vor und sprechen darüber, warum PM2 benötigt wird und wie Sie PM2 installieren und verwenden. Ich hoffe, dass es für alle hilfreich ist!

Detaillierte Erläuterungs- und Installationshandbuch für Pinetwork -Knoten In diesem Artikel wird das Pinetwork -Ökosystem im Detail vorgestellt - PI -Knoten, eine Schlüsselrolle im Pinetwork -Ökosystem und vollständige Schritte für die Installation und Konfiguration. Nach dem Start des Pinetwork -Blockchain -Testnetzes sind PI -Knoten zu einem wichtigen Bestandteil vieler Pioniere geworden, die aktiv an den Tests teilnehmen und sich auf die bevorstehende Hauptnetzwerkveröffentlichung vorbereiten. Wenn Sie Pinetwork noch nicht kennen, wenden Sie sich bitte an was Picoin ist? Was ist der Preis für die Auflistung? PI -Nutzung, Bergbau und Sicherheitsanalyse. Was ist Pinetwork? Das Pinetwork -Projekt begann 2019 und besitzt seine exklusive Kryptowährung PI -Münze. Das Projekt zielt darauf ab, eine zu erstellen, an der jeder teilnehmen kann

Wie packe ich die ausführbare Datei von nodejs mit pkg? Im folgenden Artikel erfahren Sie, wie Sie mit pkg ein Node-Projekt in eine ausführbare Datei packen. Ich hoffe, dass er Ihnen weiterhilft!

npm node gyp schlägt fehl, weil „node-gyp.js“ nicht mit der Version von „Node.js“ übereinstimmt. Die Lösung ist: 1. Löschen Sie den Knotencache über „npm cache clean -f“ 2. Über „npm install -“ g n“ Installieren Sie das n-Modul. 3. Installieren Sie die Version „node v12.21.0“ über den Befehl „n v12.21.0“.

Was ist ein Single-Sign-On-System? Wie implementiert man es mit NodeJS? Im folgenden Artikel erfahren Sie, wie Sie mit Node ein Single-Sign-On-System implementieren. Ich hoffe, dass er Ihnen weiterhilft!
