SORU
2 HAZİRAN 2012, CUMARTESİ


Çö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.

http://golang.org/doc/effective_go.html#functions

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
3 HAZİRAN 2012, Pazar


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.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • ChannelRichard

    ChannelRicha

    7 Kasım 2008
  • Garrett Müller

    Garrett Mül

    26 HAZİRAN 2009
  • Sorikan

    Sorikan

    3 ŞUBAT 2008