2016-04-10 35 views
1

VM'ler ve davranışları hakkındaki mevcut varsayımları temel alarak, tanımlarının her vurulduğunda kapakların tahsis edildiğini ve derlendiğini düşünüyorum; Birbirine tahsis edilen ve bir kez derlenen kapanışlar dışında ilan edilen işlevlerin aksine (bir yere yerleştirildikleri için tanımları sadece bir kez vurulur). Bu varsayım doğru mu?Kapılar Node.js V8'de ne zaman ayrılır ve derlenir?

kapatma veri soket tarafından alınan her zaman socket.on('data', function (data) {...}) bir kapatma var ise, V8 yeni bellek ayırır (ve muhtemelen yeniden derler)?

VM en konusunda şimdiki varsayımlar ve bunların davranışlarına dayanarak

cevap

5

Ben kapanışları tahsis ve onların tanımı gerçekten

Değil

isabet her zaman derlenmektedir anlamaya. Kapanışlar, numaralı telefondan derlenir, ancak her defasında tanımlıdır ve tanımları her defasında olarak belirtilir. En önemlisi, tahsisi ve derlemeyi ayırmanız gerekir.

  • Her işlevin kodu (yani aynı kaynak kodunda yer) tek fonksiyonu farklı ortamlarda defalarca örneği bile, bir kez derlenmektedir.
    Her örneklemin derlenmesi anlamsız olurdu, tıpkı her bir çağrı için derlenmesinin anlamsız olması gibi (tam anlamıyla bir "yorumlayıcının" yaptığı ve sınırların akışkan olduğu, örneğin, daha önce olmayan tembel derleme için) ilk aramanın süresi.
    Kod, bir optimizasyon adayı haline gelirse, ya da optimizasyon başarısız olursa ve düzeltilmesi gerektiğinde yeniden derlenebilir (daha yavaş ancak daha karmaşık bir derleyici ile); ama bu nokta dışında.Her işlev, tanımı yapıldığı zaman, özellikle yerel işlevler (diğer işlevlerde yuvalanmış) ile ilgili olduğunda, atanır/örneklenir.
    Kapatma işlevleri için ayırma maliyeti sıfırdır, ancak hiçbir ortam göstericisinin depolanması gerekmediğinden örnek nesnelere gerek yoktur. Ben socket.on('data', function (data) {...}) bir kapatma varsa

Yani, V8 (ve büyük olasılıkla yeniden derler) yeni bellek her zaman veri soket tarafından alındığı kapatılmasını ayırır?

değil function (data) {…}

, bu sadece bir kere ve on çağrısına geçirilir.

Ama evet, bölümünde başlatılan bir kapatmanız varsa, bu her veri alındığında ve işleyici çağrıldığında bazı bellekler atayacaktır. Ama bunun için endişelenmenize gerek yok, bellek tahsisi ucuz ve hızlı.

Teknik detaylar arıyorsanız, http://mrale.ph/blog/2012/09/23/grokking-v8-closures-for-fun.html'u (zaten birkaç yaşında olmasına rağmen) okumanızı tavsiye ederim.

+0

Gerçekten teknik bir cevap. Cevap için teşekkürler. Bir özet eklemek için yayınınızı düzenledim. Lütfen bununla ilgili olup olmadığına bakın .. –

+0

Ve "farklı ortamların" ne anlama geldiğini açıklayabilir misiniz? Aynı modül birden fazla modül tarafından çağrılmış mı demek istiyorsunuz? Ve bir uyarı geldiğini söylediniz: optimizasyon adayları birçok kez derlendi. "Optimizasyon adayı" olarak nitelendirilen nedir? –

+0

@Geotarget: A * sözcüksel * ortam, işlevin kapsamı, yani kapağın kapanacağı şey. Yığın içinde ayrılması gereken şey (kapalı-olmayan ortamlar için her zamanki gibi yığının aksine) ve kapanmanın hatırlanması gereken şey. – Bergi

2

, ben kapanışları tahsis ve bunların tanımı isabet her zaman derlenmektedir anlamaya;

doğru fonksiyonlardan farklı olarak

kez tahsis ve derlenen dış kapanışları ilan etti.

yanlış, bunlar da kendi tanım isabet her zaman derlenen, ancak bunlar genellikle tanım sadece bir kez vurmak olacak bir yere en konulur.
Kapanışlar, birden çok kez tanımlanacak şekilde tasarlanmıştır ve her defasında farklı değişkenler/değerler içerir.
bu basit/anonim işlev veya

V8 her zaman veri soket

hayır tarafından alındığında yeni bellek ayırır bir kapaktır Hava differentiatte nasıl , bu anonim işlev Bir kez derlenir ve daha sonra olay işleyicisine iletilir. Olay işleyicisi artık bu işleve bir referans veriyor ve her veri alındığında bunu çağırıyor.

Bu örnekteki tanım, olay dinleyicisini eklerken yalnızca bir kez vurulur.