programm에 거대한 메모리 블록을 할당하면 방금 알아 챘습니다. GC는 모든 프로그램 시간을 먹을 것입니다.큰 할당 된 데이터 블록에 거대한 GC 퍼포먼스 문제가 발생했습니다.
여기 POC가 있습니다.
func main() {
//////////////// !!!!!!!
/* If I uncomment 2 lines below programm runs fast */
nodesPool := make([]int, 300e6, 300e6)
_ = nodesPool
//////////////////////7
file, _ := os.Open("result.txt")
defer file.Close()
reader := bufio.NewReader(file)
var lastLinkIdx = 1 // Dont use first element use 0 as saver
cnt:= 0
totalB := 0
for {
l, err := reader.ReadString('\n')
if err == io.EOF {
fmt.Println("EOF")
break
}
cnt+=1
totalB+=len(l)
lines := strings.Split(l, ":")
nodeId,_ := strconv.Atoi(lines[0])
_ = nodeId
linkIdsStr := strings.Split(lines[1], ",")
var ii = len(linkIdsStr)
_ = ii
/* ... */
}
fmt.Println("pool ",cnt,totalB,lastLinkIdx)
}
https://gist.github.com/martende/252f403f0c17cb489de4
가 나는 GC에서 메모리를 할당하지만,도에서는 ReadLine이 그것을 필요로 becuase 다른 모든 라이브러리 GC를 떠나 실제로 가능하다 GC가 어떻게 든 큰 메모리 블록을 이동 시도합니다 생각합니다.여기에는 메모리 블록이있는 프로파일 링이 있습니다.
Total: 1445 samples
428 29.6% 29.6% 722 50.0% runtime.sweepone
375 26.0% 55.6% 375 26.0% markroot
263 18.2% 73.8% 263 18.2% runtime.xadd
116 8.0% 81.8% 116 8.0% strings.Count
98 6.8% 88.6% 673 46.6% strings.genSplit
34 2.4% 90.9% 44 3.0% runtime.MSpan_Sweep
25 1.7% 92.7% 729 50.4% MCentral_Grow
17 1.2% 93.8% 19 1.3% syscall.Syscall
9 0.6% 94.5% 9 0.6% runtime.memclr
9 0.6% 95.1% 9 0.6% runtime.memmove
여기에는 메모리 블록이없는 프로파일 링이 있습니다. 이동 팀 says이의
98 27.0% 27.0% 98 27.0% strings.Count
93 25.6% 52.6% 228 62.8% strings.genSplit
45 12.4% 65.0% 45 12.4% scanblock
24 6.6% 71.6% 28 7.7% runtime.MSpan_Sweep
13 3.6% 75.2% 74 20.4% runtime.mallocgc
12 3.3% 78.5% 12 3.3% runtime.memclr
8 2.2% 80.7% 8 2.2% MHeap_ReclaimList
8 2.2% 82.9% 11 3.0% syscall.Syscall
6 1.7% 84.6% 44 12.1% MHeap_Reclaim
6 1.7% 86.2% 6 1.7% markonly
3 억 개의 정수를 배열하고 있다는 것을 알게됩니다. –
1. 어떤 Go 버전입니까? 2. 노드 풀은 (너무) 커졌습니다. 3. GC가 움직이지 않는다. 4. GC되지 않은 메모리를 할당하는 영리하고 쉬운 방법은 없습니다. – Volker
go1.3 linux/amd64 nodePool은 크지 만 실제로 필요합니다. – Oleg