真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Go 簡單入門

GO的環(huán)境配置?

GOPATH GOROOT 都是干嘛用的?

創(chuàng)新互聯(lián)是一家專業(yè)的成都網(wǎng)站建設(shè)公司,我們專注成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、網(wǎng)絡(luò)營銷、企業(yè)網(wǎng)站建設(shè),賣鏈接,廣告投放平臺(tái)為企業(yè)客戶提供一站式建站解決方案,能帶給客戶新的互聯(lián)網(wǎng)理念。從網(wǎng)站結(jié)構(gòu)的規(guī)劃UI設(shè)計(jì)到用戶體驗(yàn)提高,創(chuàng)新互聯(lián)力求做到盡善盡美。

配置環(huán)境跟java對(duì)比有點(diǎn)奇怪

https://blog.csdn.net/weixin_/article/details/

語言特性

協(xié)程?

建立一個(gè)協(xié)程很簡單 加一個(gè)go關(guān)鍵字就可以

package concurrence

import (
	"fmt"
	"time"
)

func hello(i int) {
	println("hello goroutine : " + fmt.Sprint(i))
}

func HelloGoRoutine() {
	for i := 0; i < 5; i++ {
		go func(j int) {
			hello(j)
		}(i)
	}
	time.Sleep(time.Second)
}

通過通信共享內(nèi)存而不是通過共享內(nèi)存而實(shí)現(xiàn)通信?

先提供一個(gè)或多個(gè)高性能隊(duì)列,線程/進(jìn)程/微服務(wù)之間需要訪問別人時(shí),不能直接讀寫別人的數(shù)據(jù),而要通過隊(duì)列提出請(qǐng)求,然后在對(duì)方處理請(qǐng)求時(shí)再做相應(yīng)處理。

Q&A

Q:我對(duì)java比較熟悉,java里面通過鎖來實(shí)現(xiàn)共享內(nèi)存,從而實(shí)現(xiàn)通信。 那啥叫”通過通信共享內(nèi)存“?。?/p>

A:ultimate go notebook 里面講把channel當(dāng)做信號(hào)收發(fā),而不是一種數(shù)據(jù)結(jié)構(gòu)。

Q:我可以理解成chenel在go里 就像 阻塞隊(duì)列BlockingQueu在java里嗎? 只不過chenel顆粒度更小實(shí)現(xiàn)的更加底層?

A:無人回復(fù)。。。。

https://juejin.cn/post//#heading-14
https://draveness.me/whys-the-design-communication-shared-memory/

Channel?

make(chan元素類型,[緩沖大小])·

  • 無緩沖通道 make(chan int)
  • 有緩沖通道 make(chan int,2)

例子:一個(gè)經(jīng)典的生產(chǎn)消費(fèi)模型

package concurrence

func CalSquare() {
	src := make(chan int)
	dest := make(chan int, 3)
	go func() {
		defer close(src)
		for i := 0; i < 10; i++ {
			src <- i
		}
	}()
	go func() {
		defer close(dest)
		for i := range src {
			dest <- i * i
		}
	}()
	for i := range dest {
		//復(fù)雜操作
		println(i)
	}
}

LOCK?

package concurrence

import (
	"sync"
	"time"
)

var (
	x    int64
	lock sync.Mutex
)

func addWithLock() {
	for i := 0; i < 2000; i++ {
		lock.Lock()
		x += 1
		lock.Unlock()
	}
}
func addWithoutLock() {
	for i := 0; i < 2000; i++ {
		x += 1
	}
}

func Add() {
	x = 0
	for i := 0; i < 5; i++ {
		go addWithoutLock()
	}
	time.Sleep(time.Second)
	println("WithoutLock:", x)
	x = 0
	for i := 0; i < 5; i++ {
		go addWithLock()
	}
	time.Sleep(time.Second)
	println("WithLock:", x)
}

func ManyGoWait() {
	var wg sync.WaitGroup
	wg.Add(5)
	for i := 0; i < 5; i++ {
		go func(j int) {
			defer wg.Done()
			hello(j)
		}(i)
	}
	wg.Wait()
}

內(nèi)存管理

相關(guān)概念

  • Mutator:業(yè)務(wù)線程,分配新對(duì)象,修改對(duì)象指向關(guān)系

  • Collector: GC線程,找到存活對(duì)象,回收死亡對(duì)象的內(nèi)存空間. Serial GC:只有一個(gè)collector

  • Parallel GC;:支持多個(gè)collectors同時(shí)回收的 GC算法.

  • Concurrent GC: mutator(s)和collector(s)可以同時(shí)執(zhí)行

    ? Collectors必須感知對(duì)象指向關(guān)系的改變!

ConcurrentGC 的實(shí)現(xiàn)方式

  • 三色標(biāo)記
  • 混合寫屏障

追蹤垃圾回收

可達(dá)性分析

  • 對(duì)象被回收的條件:指針指向關(guān)系不可達(dá)的對(duì)象

  • 標(biāo)記根對(duì)象

    靜態(tài)變量、全局變量、常量、線程棧等

  • 標(biāo)記:找到可達(dá)對(duì)象
    求指針指向關(guān)系的傳遞閉包:從根對(duì)象出發(fā),找到所有可達(dá)對(duì)象

  • 清理:所有不可達(dá)對(duì)象
    將存活對(duì)象復(fù)制到另外的內(nèi)存空間(Copying GC)
    將死亡對(duì)象的內(nèi)存標(biāo)記為句分配“(Mark-sweep GC)

    移動(dòng)并整理存活對(duì)象(Mark-compact GC)

  • 根據(jù)對(duì)象的生命周期,使用不同的標(biāo)記和清理策略

引用計(jì)數(shù)

  • 每個(gè)對(duì)象都有一個(gè)與之關(guān)聯(lián)的引用數(shù)目
  • 對(duì)象存活的條件:當(dāng)且僅當(dāng)引用數(shù)大于0
  • 優(yōu)點(diǎn):
    內(nèi)存管理的操作被平攤到程序執(zhí)行過程中
    內(nèi)存管理不需要了解runtime的實(shí)現(xiàn)細(xì)節(jié):C++智能指針(smart pointer)
  • 缺點(diǎn):
    維護(hù)引用計(jì)數(shù)的開銷較大:通過原子操作保證對(duì)引用計(jì)數(shù)操作的原子性可見性
  • 無法回收環(huán)形數(shù)據(jù)結(jié)構(gòu)—— weak reference (swift 使用了 weal reference,相對(duì)解決了引用計(jì)數(shù)無法回收環(huán)形數(shù)據(jù)結(jié)構(gòu)的問題)
    內(nèi)存開銷:每個(gè)對(duì)象都引入的額外內(nèi)存空間存儲(chǔ)引用數(shù)目
  • 回收內(nèi)存時(shí)依然可能引發(fā)暫停

分塊

  • 目標(biāo):為對(duì)象在heap 上分配內(nèi)存·提前將內(nèi)存分塊

  • 調(diào)用系統(tǒng)調(diào)用mmap()向OS申請(qǐng)一大塊內(nèi)存,例如4 MB·先將內(nèi)存劃分成大塊,例如8KB,稱作mspan

    再將大塊繼續(xù)劃分成特定大小的小塊,用于對(duì)象分配

    noscan nspan:分配不包含指針的對(duì)象——GC不需要掃描

    scan mspan:分配包含指針的對(duì)象—— GC需要掃描

  • 對(duì)象分配:根據(jù)對(duì)象的大小,選擇最合適的塊返回

緩存

  • TCMalloc: thread caching
  • 每個(gè)p包含一個(gè)nrache用于快速分配,用于為綁定于p上的g分配對(duì)象
  • mcache管理一組mspan
  • 當(dāng)mcache中的nspan分配完畢,向mcentral申請(qǐng)帶有未分配塊的mspan
  • 當(dāng)ms pan中沒有分配的對(duì)象,ns pan會(huì)被緩存在mcentral中,而不是立刻釋放并歸還給OS

內(nèi)存管理優(yōu)化

  • 對(duì)象分配是非常高頻的操作:每秒分配GB級(jí)別的內(nèi)存
  • 小對(duì)象占比較高
  • Go內(nèi)存分配比較耗時(shí)
    分配路徑長:g -> m->p -> mache -> ms pan -> memory block -> return pointer.
  • pprof:對(duì)象分配的函數(shù)是最頻繁調(diào)用的函數(shù)之一

Balanced GC(根據(jù)對(duì)象的生命周期,使用不同的標(biāo)記和清理策略)

小對(duì)象的管理

  • 每個(gè)g 都綁定一大塊內(nèi)存(1KB),稱作 goroutine allocation buffer (GAB
  • GAB用于noscan類型的小對(duì)象分配:<128 B
  • 使用三個(gè)指針維護(hù)GAB: base, end, top
  • Bump pointer(指針碰撞)風(fēng)格對(duì)象分配
    無須和其他分配請(qǐng)求互斥
    分配動(dòng)作簡單高效

大對(duì)象的管理

  • GAB對(duì)于Go內(nèi)存管理來說是一個(gè)對(duì)象

  • 本質(zhì):將多個(gè)小對(duì)象的分配合并成一次達(dá)對(duì)象的分配

  • 問題:GAB的對(duì)象分配方式會(huì)導(dǎo)致內(nèi)存被延遲釋放

  • 方案:移動(dòng) GAB中存活的對(duì)象

    當(dāng)GAB總大小超過一定閾值時(shí),將GAB中存活的對(duì)象復(fù)制到另外分配的GAB中

    原先的 GAB可以釋放,避免內(nèi)存泄漏

    本質(zhì):用copying GC的算法管理小對(duì)象


網(wǎng)站名稱:Go 簡單入門
標(biāo)題路徑:http://weahome.cn/article/dsoisoi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部