Çöp toplama ile ilgilidir Git yapılar olan vs yığın yığın ayırma ve
Ben yeni Gidip geldim yaşıyor biraz congitive arasındaki uyumsuzluk C-stil yığın tabanlı programlama otomatik değişkenler canlı yığını ve ayrılan bellek yaşıyor öbek ve Python tarzı bir yığın tabanlı-programlama tek bir şey yaşayan yığını olan başvurular/işaretçiler için nesneler yığını.
Söyleyebileceğim kadarıyla, iki aşağıdaki işlevleri aynı çıktıyı verir:
func myFunction() (*MyStructType, error) {
var chunk *MyStructType = new(HeaderChunk)
...
return chunk, nil
}
func myFunction() (*MyStructType, error) {
var chunk MyStructType
...
return &chunk, nil
}
yani yeni bir yapı tahsis ve iade.
Eğer C bunu ben yazsaydım, ilk öbek üzerinde bir nesne koymak olurdu ve ikinci yığın üzerine koymak olurdu. İlk Kötü bir Şey olacağını işlevini yerine döndü zaman buharlaşmış olurdu yığın işaretçisi, ikinci yığın için bir işaretçi dönmek istiyorsunuz, o, dönecekti.
Eğer Python ile yazmış olsaydım (veya C dışında diğer pek çok modern diller#) örnek 2 mümkün olmazdı.
Git çöp her iki değeri toplar, yukarıdaki formları ikisi de iyi yani.
Alıntı için:
C aksine, son derece iyi bir adresini dönmek için olduğunu unutmayın yerel değişken; depolama değişken hayatta ile ilgili işlev verir. Aslında, bir kompozit adresini alma biz değerlendirme, yeni bir örneğini her zaman değişmez ayırır bu son iki satır birleştirin.
Ama birkaç soru yükseltir.
1 - örnek 1'de, yapı yığında bildirildi. Ne örnek 2 hakkında? C olurdu aynı şekilde yığında ilan ya da öbek de gidiyor mu?
Örnek 2 - 2 yığında ilan edilir, nasıl işlevini verir, sonra mevcut kalacak mı?
Örnek 3 - 2 aslında yığında ilan edilir, nasıl yapılar referans değer yerine geçti? Bu durumda göstericiler ne anlamı var?
CEVAP
Kelimeler "" ve "yığın" her yerde dil spec görünmüyor. yığın fazlalaştı Senin soru biçimindedir "...yığında bildirilen, "...yığında ilan etti," ama bildirim sözdizimi Gitmek unutmayın yığın veya yığın. hakkında bir şey söylüyor"
Teknik olarak tüm sorularınıza cevap uygulama bağımlı yapar. Tabii ki gerçekte, yığın (başına goroutine!). ve bir yığın ve bazı şeyler yığın ve öbek üzerinde biraz üzerinde git. Bazı durumlarda derleyici aşağıdaki katı kuralları ("new her zaman ayırır öbek") ve diğerleri derleyicinin yaptığı "kaçış analizi" için karar verirseniz, bir nesne olabilir canlı yığını veya olmalı ayrılan yığın.
Örnek 2, kaçış analiz yapı göstericisi ile derleyici yapı ayırmak zorunda kalacak, böylece kaçan göstermek. Git, geçerli Uygulama Eğer adresi bir yapı herhangi bir parçası alındığında, yapı yığınına gider ki bu durumda katı bir kural ancak şöyle düşünüyorum.
3, terminoloji hakkında bocalama riski için bir soru. Gitmek her şeye değer, referans geçmek yok geçirilir. Burada işaretçi değeri dönüyor. Göstericiler ne anlamı var? Örnek: aşağıdaki değişiklik düşünün
type MyStructType struct{}
func myFunction1() (*MyStructType, error) {
var chunk *MyStructType = new(MyStructType)
// ...
return chunk, nil
}
func myFunction2() (MyStructType, error) {
var chunk MyStructType
// ...
return chunk, nil
}
type bigStruct struct {
lots [1e6]float64
}
func myFunction3() (bigStruct, error) {
var chunk bigStruct
// ...
return chunk, nil
}
MyFunction2 yapı adresi yerine yapı dönmek için değiştirdim. MyFunction1 ve myFunction2 şimdi, Kurul çıkışı karşılaştırın
--- prog list "myFunction1" ---
0000 (s.go:5) TEXT myFunction1 0(SB),$16-24
0001 (s.go:6) MOVQ $type."".MyStructType 0(SB),(SP)
0002 (s.go:6) CALL ,runtime.new 0(SB)
0003 (s.go:6) MOVQ 8(SP),AX
0004 (s.go:8) MOVQ AX,.noname 0(FP)
0005 (s.go:8) MOVQ $0,.noname 8(FP)
0006 (s.go:8) MOVQ $0,.noname 16(FP)
0007 (s.go:8) RET ,
--- prog list "myFunction2" ---
0008 (s.go:11) TEXT myFunction2 0(SB),$0-16
0009 (s.go:12) LEAQ chunk 0(SP),DI
0010 (s.go:12) MOVQ $0,AX
0011 (s.go:14) LEAQ .noname 0(FP),BX
0012 (s.go:14) LEAQ chunk 0(SP),BX
0013 (s.go:14) MOVQ $0,.noname 0(FP)
0014 (s.go:14) MOVQ $0,.noname 8(FP)
0015 (s.go:14) RET ,
MyFunction1 çıktı burada peterSO (mükemmel) cevap farklı merak etme. Belli ki farklı Derleyiciler yapıyoruz. Aksi takdirde, myStructType yerine *myStructType dönmek için myFunction2 ben modfied. Arama zamanı.yeni bazı durumlarda iyi bir şey olurdu gitti. Ama bekle, myFunction3, burada
--- prog list "myFunction3" ---
0016 (s.go:21) TEXT myFunction3 0(SB),$8000000-8000016
0017 (s.go:22) LEAQ chunk -8000000(SP),DI
0018 (s.go:22) MOVQ $0,AX
0019 (s.go:22) MOVQ $1000000,CX
0020 (s.go:22) REP ,
0021 (s.go:22) STOSQ ,
0022 (s.go:24) LEAQ chunk -8000000(SP),SI
0023 (s.go:24) LEAQ .noname 0(FP),DI
0024 (s.go:24) MOVQ $1000000,CX
0025 (s.go:24) REP ,
0026 (s.go:24) MOVSQ ,
0027 (s.go:24) MOVQ $0,.noname 8000000(FP)
0028 (s.go:24) MOVQ $0,.noname 8000008(FP)
0029 (s.go:24) RET ,
Hala hiçbir çalışma zamanı için arayın.yeni, ve evet gerçekten 8 MB nesneyi döndürmek için değerine göre çalışır. Çalışır, ama genellikle istemezdi. Bir işaretçi noktası burada 8 cisimler etrafında önlemek için olacaktır.

Daha hızlı olan: ayırma ya da Yığın Yı...
Özel durum açıklaması ve yığın bir ist...
ayırma vektörler yığın bellek veya yığ...
java statik ayırma - yığın, yığın ve k...
Aslında bir Yığın Taşma hatası neden o...