Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Analysis of GC process in Go language

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

< s.base()+s.elemsize; oblet += maxObletBytes { if !gcw.putFast(oblet) { gcw.put(oblet) } } } // Compute the size of the oblet. Since this object // must be a large object, s.base() is the beginning // of the object. n = s.base() + s.elemsize - b if n >

MaxObletBytes {n = maxObletBytes}} var i uintptr for i = 0; I

< n; i += sys.PtrSize { // Find bits for this word. // 获取到对应的bits if i != 0 { // Avoid needless hbits.next() on last iteration. hbitshbits = hbits.next() } // Load bits once. See CL 22712 and issue 16973 for discussion. bits := hbits.bits() // During checkmarking, 1-word objects store the checkmark // in the type bit for the one word. The only one-word objects // are pointers, or else they'd be merged with other non-pointer // data into larger allocations. if i != 1*sys.PtrSize && bits&bitScan == 0 { break // no more pointers in this object } // 不是指针,继续 if bits&bitPointer == 0 { continue // not a pointer } // Work here is duplicated in scanblock and above. // If you make changes here, make changes there too. obj := *(*uintptr)(unsafe.Pointer(b + i)) // At this point we have extracted the next potential pointer. // Quickly filter out nil and pointers back to the current object. if obj != 0 && obj-b >

< endOffset; tmptmp = tmp.next { if tmp.kind == _KindSpecialFinalizer { // Stop freeing of object if it has a finalizer. mbits.setMarkedNonAtomic() hasFin = true break } } // Pass 2: queue all finalizers _or_ handle profile record. for special != nil && uintptr(special.offset) < endOffset { // Find the exact byte for which the special was setup // (as opposed to object beginning). p := s.base() + uintptr(special.offset) if special.kind == _KindSpecialFinalizer || !hasFin { // Splice out special record. y := special specialspecial = special.next *specialspecialp = special freespecial(y, unsafe.Pointer(p), size) } else { // This is profile record, but the object has finalizers (so kept alive). // Keep special record. specialp = &special.next special = *specialp } } } else { // object is still live: keep special record specialp = &special.next special = *specialp } } if debug.allocfreetrace != 0 || raceenabled || msanenabled { // Find all newly freed objects. This doesn't have to // efficient; allocfreetrace has massive overhead. mbits := s.markBitsForBase() abits := s.allocBitsForIndex(0) for i := uintptr(0); i < s.nelems; i++ { if !mbits.isMarked() && (abits.index < s.freeindex || abits.isMarked()) { x := s.base() + i*s.elemsize if debug.allocfreetrace != 0 { tracefree(unsafe.Pointer(x), size) } if raceenabled { racefree(unsafe.Pointer(x), size) } if msanenabled { msanfree(unsafe.Pointer(x), size) } } mbits.advance() abits.advance() } } // Count the number of free objects in this span. // 获取需要释放的alloc对象的总数 nalloc := uint16(s.countAlloc()) // 如果sizeclass为0,却分配的总数量为0,则释放到mheap if spc.sizeclass() == 0 && nalloc == 0 { s.needzero = 1 freeToHeap = true } nfreed := s.allocCount - nalloc if nalloc >

S.allocCount {print ("runtime: nelems=", s.nelems, "nalloc=", nalloc, "previous allocCount=", s.allocCount, "nfreed=", nfreed, "\ n") throw ("sweep increased allocation count")} s.allocCount = nalloc / / determine whether span is empty wasempty: = s.nextFreeIndex () = s.nelems / / reset freeindex s.freeindex = 0 / / reset allocation index to start of span. If trace.enabled {getg () .m.p.ptr () .traceReclaimed + = uintptr (nfreed) * s.elemsize} / / gcmarkBits becomes the allocBits. / / get a fresh cleared gcmarkBits in preparation for next GC / / reset allocBits to gcMarkBits ss.allocBits = s.gcmarkBits / / reset gcMarkBits s.gcmarkBits = newMarkBits (s.nelems) / / Initialize alloc bits cache. / / Update allocCache s.refillAllocCache (0) / / We need to set s.sweepgen = h.sweepgen only when all blocks are swept, / / because of the potential for a concurrent free/SetFinalizer. / / But we need to set it before we make the span available for allocation / / (return it to heap or mcentral), because allocation code assumes that a / / span is already swept if available for allocation If freeToHeap | | nfreed = 0 {/ / The span must be in our exclusive ownership until we update sweepgen, / / check for potential races. If s.state! = mSpanInUse | | s.sweepgen! = sweepgen-1 {print ("MSpan_Sweep: state=", s.state, "sweepgen=", s.sweepgen, "mheap.sweepgen=", sweepgen, "\ n") throw ("MSpan_Sweep: bad span state after sweep")} / / Serialization point. / / At this point the mark bits are cleared and allocation ready / / to go so release the span. Atomic.Store (& s.sweepgen, sweepgen)} if nfreed > 0 & & spc.sizeclass ()! = 0 {c.local_nsmallfree [spc.sizeclass ()] + = uintptr (nfreed) / / release span on mcentral res = mheap_. centralized [SPC] .mcentral.freeSpan (s, preserve Wasempty) / / MCentral_FreeSpan updates sweepgen} else if freeToHeap {/ / here is the span release of large objects Echo / / Free large span to heap / / NOTE (rsc,dvyukov): The original implementation of efence / / in CL 22060046 used SysFree instead of SysFault, so that / / the operating system would eventually give the memory / / back to us again, so that an efence program could run / / longer without running out of memory. Unfortunately, / / calling SysFree here without any kind of adjustment of the / / heap data structures means that when the memory does / / come back to us, we have the wrong metadata for it, either in / / the MSpan structures or in the garbage collection bitmap. / / Using SysFault here means that the program will run out of / / memory fairly quickly in efence mode, but at least it won't / / have mysterious crashes due to confused memory reuse. / / It should be possible to switch back to SysFree if we also / / implement and then call some kind of MHeap_DeleteSpan. If debug.efence > 0 {s.limit = 0 / / prevent mlookup from finding this span sysFault (unsafe.Pointer (s.base ()), size)} else {/ / release sapn to mheap mheap_.freeSpan (s) 1)} c.localroomnlargefreeboards + c.local_largefree + = size res = true} if! res {/ / The span has been swept and is still in-use, so put / / it on the swept in-use list. / / if span is not released to mcentral or mheap, it means that span is still in in-use state mheap_. sweepSpans [2% 2] .push (s)} return res} at this point, the study of "GC process parsing of Go language" is over. I hope to solve everyone's doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report