Membebaskan sumber daya di GO

Go adalah bahasa dengan manajemen memori otomatis: pengumpul sampah, tanpa membutuhkan programmer, menangani pemulihan memori yang digunakan oleh objek yang tidak lagi digunakan oleh program. Tetapi semua otomatisasi secara keseluruhan dibatasi oleh memori - kita masih perlu menjaga sumber daya lainnya yang digunakan oleh program itu sendiri.





Sumber gambar: http://kenimation.net/doctor-who%E2%80%AC-dalek/
Sumber gambar: http://kenimation.net/doctor-who%E2%80%AC-dalek/

, - , runtime.SetFinalizer. , , . Go - , , , , .





, - . , , - , .





res1, err := NewResource1()
if err != nil {
    return nil, err
}

res2, err := NewResource2(res1)
if err != nil {
  res1.Close()
  return nil, err
}

res3, err := NewResource3(res2)
if err != nil {
  res2.Close()
  res1.Close()
  return nil, err
}

v, err := res3.DoSomething()
if err != nil {
  res3.Close()
  res2.Close()
  res1.Close()
  return nil, err
}

res3.Close()
res2.Close()
res1.Close()
return v, nil
      
      



, . , ( ). Close , - .





. , C# Java using statement try-with-resources statement . Go , , defer statement. , :





res1, err := NewResource1()
if err != nil {
  return nil, err
}
defer res1.Close()

res2, err := NewResource2(res1)
if err != nil {
  return nil, err
}
defer res2.Close()

res3, err := NewResource3(res2)
if err != nil {
  return nil, err
}
defer res3.Close()

return res3.DoSomething()
      
      



Close . Close - .





, . - defer . , , - , . , , . , , - , - - , (, main), , , , , .





, Wire. ( Wire) . . cleanup function, . .





Dedicated finalization

, c cleanup function, Wire, . , Close ( ) :





  • ;





  • .





, , , . , Go :





res, cleanup, err := NewResource()
if err != nil {
  return err
}
//    cleanup,     .

if err := res.DoSomething(); err != nil {
  return err
}
      
      



, (, ) ( ) . , " ", , , "" "" , .





Composite finalization

defer (, ), :





func Finalize(finalizers ...func()) {
  //     .
  for i := len(finalizers) - 1; i >= 0; i-- {
    func() {
      defer func() {
        //      ,    .
        //        multierror :
        // 1)    ;
        // 2)    .
        recover()
      }()
      finalizers[i]()
    }()
  }
}

func NewResource3() (*Resource3, func(), error) {
  var (
    finalizers []func() //    
    successful bool     //    
  )
  defer func() {
    //       ,
    //        -
    //       .
    if !successfull {
      Finalize(finalizers...)
    }
  }()
  
  res1, fin1, err := NewResource1()
  if err != nil {
    return nil, nil, err
  }
  finalizers = append(finalizers, fin1)
  
  res2, fin2, err := NewResource2(res1)
  if err != nil {
    return nil, nil, err
  } 
  finalizers = append(finalizers, fin2)
  
  res3 := &Resource3{
    resource2: res2,
  }
  fin3 := func() {
    Finalize(finalizers...)
  }
  
  //        .
  //        
  //     .
  successful = true
  return res3, fin3, nil
}
      
      



Finalize - .





new - error - defer , , , , .





KDone

Saya telah memposting pustaka KDone yang menyediakan seperangkat alat di atas. Dia adalah bagian dari proyek Kata , yang akan dibahas selanjutnya. Kita dapat berasumsi bahwa saat ini API-nya stabil dan jika berubah, itu tidak akan signifikan - meskipun demikian, pustaka tersebut masih baru dan saya masih menggunakan versi nol utama jika terjadi perubahan yang tidak terduga.





Konstruktor tipikal yang menggunakan pustaka ini terlihat seperti ini:





func NewResource(...) (res Resource, dtor kdone.Destructor, err error) {
  
  defer kerror.Catch(&err)               //    
                                         //   KError.
                                         //    .
  
  reaper := kdone.NewReaper()            //  reaper.
  defer reaper.MustFinalize()            //   
                                         //   .
  
  // ... reaper.MustAssume(dtor) ...     //   reaper 
                                         //    
                                         // .
  
  return res, reaper.MustRelease(), nil  //  reaper  
                                         //      
                                         //  .
}
      
      



Bagaimana menurut anda? Konsepnya cukup sederhana, tetapi mungkin saya melewatkan sesuatu dalam penalaran saya? Atau apakah Anda punya saran untuk perbaikan? Saya akan senang berdiskusi di komentar.








All Articles