日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Go 內存優化與垃圾收集

來源: 責編: 時間:2024-01-15 17:10:40 265觀看
導讀Go提供了自動化的內存管理機制,但在某些情況下需要更精細的微調從而避免發生OOM錯誤。本文將討論Go的垃圾收集器、應用程序內存優化以及如何防止OOM(Out-Of-Memory)錯誤。Go中的堆(Heap)棧(Stack)我不會詳細介紹垃圾收

Go提供了自動化的內存管理機制,但在某些情況下需要更精細的微調從而避免發生OOM錯誤。本文將討論Go的垃圾收集器、應用程序內存優化以及如何防止OOM(Out-Of-Memory)錯誤。x5j28資訊網——每日最新資訊28at.com

x5j28資訊網——每日最新資訊28at.com

Go中的堆(Heap)棧(Stack)

我不會詳細介紹垃圾收集器如何工作,已經有很多關于這個主題的文章和官方文檔(比如A Guide to the Go Garbage Collector[2]和源碼[3])。但是,我會提到一些有助于理解本文主題的基本概念。x5j28資訊網——每日最新資訊28at.com

你可能已經知道,Go的數據可以存儲在兩個主要的內存存儲中: 棧(stack)和堆(heap)。x5j28資訊網——每日最新資訊28at.com

x5j28資訊網——每日最新資訊28at.com

通常,棧存儲的數據的大小和使用時間可以由Go編譯器預測,包括函數局部變量、函數參數、返回值等。x5j28資訊網——每日最新資訊28at.com

棧是自動管理的,遵循后進先出(LIFO)原則。當調用函數時,所有相關數據都放在棧的頂部,函數結束時,這些數據將從棧中刪除。棧不需要復雜的垃圾收集機制,其內存管理開銷最小,在棧中檢索和存儲數據的過程非???。x5j28資訊網——每日最新資訊28at.com

然而,并不是所有數據都可以存儲在棧中。在執行過程中動態更改的數據或需要在函數范圍之外訪問的數據不能放在棧上,因為編譯器無法預測其使用情況,這種數據應該存儲在堆中。x5j28資訊網——每日最新資訊28at.com

與棧不同,從堆中檢索數據并對其進行管理的成本更高。x5j28資訊網——每日最新資訊28at.com

棧里放什么,堆里放什么?

正如前面提到的,棧用于具有可預測大小和壽命的值,例如:x5j28資訊網——每日最新資訊28at.com

  • 在函數內部聲明的局部變量,例如基本數據類型變量(例如數字和布爾值)。
  • 函數參數。
  • 函數返回后不再被引用的返回值。

Go編譯器在決定將數據放在棧中還是堆中時會考慮各種細微差別。x5j28資訊網——每日最新資訊28at.com

例如,預分配大小為64 KB的數據將存儲在棧中,而大于64 KB的數據將存儲在堆中。這同樣適用于數組,如果數組超過10 MB,將存儲在堆中。x5j28資訊網——每日最新資訊28at.com

可以使用逃逸分析(escape analysis)來確定特定變量的存儲位置。x5j28資訊網——每日最新資訊28at.com

例如,可以通過命令行編譯參數-gcflags=-m來分析應用程序:x5j28資訊網——每日最新資訊28at.com

go build -gcflags=-m main.go

如果使用-gcflags=-m參數編譯下面的main.go:x5j28資訊網——每日最新資訊28at.com

package mainfunc main() {  var arrayBefore10Mb [1310720]int  arrayBefore10Mb[0] = 1  var arrayAfter10Mb [1310721]int  arrayAfter10Mb[0] = 1  sliceBefore64 := make([]int, 8192)  sliceOver64 := make([]int, 8193)  sliceOver64[0] = sliceBefore64[0]}

結果是:x5j28資訊網——每日最新資訊28at.com

# command-line-arguments./main.go:3:6: can inline main./main.go:7:6: moved to heap: arrayAfter10Mb./main.go:10:23: make([]int, 8192) does not escape./main.go:11:21: make([]int, 8193) escapes to heap

可以看到arrayAfter10Mb數組被移動到堆中,因為大小超過了10MB,而arrayBefore10Mb仍然留在棧中(對于int變量,10MB等于10 * 1024 * 1024 / 8 = 1310720個元素)。x5j28資訊網——每日最新資訊28at.com

此外,sliceBefore64沒有存儲在堆中,因為它的大小小于64KB,而sliceOver64被存儲在堆中(對于int變量,64KB等于64 * 1024 / 8 = 8192個元素)。x5j28資訊網——每日最新資訊28at.com

要了解更多關于在堆中分配的位置和內容,可以參考malloc.go源碼[4]。x5j28資訊網——每日最新資訊28at.com

因此,使用堆的一種方法是盡量避免用它!但是,如果數據已經落在堆中了呢?x5j28資訊網——每日最新資訊28at.com

與棧不同,堆的大小是無限的,并且不斷增長。堆存儲動態創建的對象,如結構體、分片和映射,以及由于其限制而無法放入棧中的大內存塊。x5j28資訊網——每日最新資訊28at.com

在堆中重用內存并防止其完全阻塞的唯一工具是垃圾收集器。x5j28資訊網——每日最新資訊28at.com

淺談垃圾收集器的工作原理

垃圾收集器(GC)是一種專門用于識別和釋放動態分配內存的系統。x5j28資訊網——每日最新資訊28at.com

Go使用基于跟蹤和標記和掃描算法的垃圾收集算法。在標記階段,垃圾收集器將應用程序正在使用的數據標記為活躍堆。然后,在清理階段,GC遍歷所有未標記為活躍的內存并復用。x5j28資訊網——每日最新資訊28at.com

垃圾收集器不是免費工作的,需要消耗兩個重要的系統資源: CPU時間和物理內存。x5j28資訊網——每日最新資訊28at.com

垃圾收集器中的內存由以下部分組成:x5j28資訊網——每日最新資訊28at.com

  • 活躍堆內存(在前一個垃圾收集周期中標記為"活躍"的內存)
  • 新的堆內存(尚未被垃圾收集器分析的堆內存)
  • 存儲元數據的內存,與前兩個實體相比,這些元數據通常微不足道。

垃圾收集器所消耗的CPU時間與其工作細節有關。有一種稱為"stop-the-world"的垃圾收集器實現,它在垃圾收集期間完全停止程序執行,導致CPU時間被花在非生產性工作上。x5j28資訊網——每日最新資訊28at.com

在Go里,垃圾收集器并不是完全"stop-the-world",而是與應用程序并行執行其大部分工作(例如標記堆)。x5j28資訊網——每日最新資訊28at.com

但是,垃圾收集器的操作仍然有一些限制,并且會在一個周期內多次完全停止工作代碼的執行,想要了解更多可以閱讀源碼[5]。x5j28資訊網——每日最新資訊28at.com

如何管理垃圾收集器

在Go中可以通過某些參數管理垃圾收集器: GOGC環境變量或runtime/debug包中的等效函數SetGCPercent。x5j28資訊網——每日最新資訊28at.com

GOGC參數確定將觸發垃圾收集的新未分配堆內存相對于活躍內存的百分比。x5j28資訊網——每日最新資訊28at.com

GOGC的默認值是100,意味著當新內存達到活躍堆內存的100%時將觸發垃圾收集。x5j28資訊網——每日最新資訊28at.com

x5j28資訊網——每日最新資訊28at.com

當新堆占用活躍堆的100%時,將運行垃圾收集器x5j28資訊網——每日最新資訊28at.com

我們以示例程序為例,通過go tool trace跟蹤堆大小的變化,我們用Go 1.20.1版本來運行程序。x5j28資訊網——每日最新資訊28at.com

在本例中,performMemoryIntensiveTask函數使用了在堆中分配的大量內存。這個函數啟動一個隊列大小為NumWorker的工作池,任務數量等于NumTasks。x5j28資訊網——每日最新資訊28at.com

package mainimport ( "fmt" "os" "runtime/debug" "runtime/trace" "sync")const ( NumWorkers    = 4     // Number of workers. NumTasks      = 500   // Number of tasks. MemoryIntense = 10000 // Size of memory-intensive task (number of elements).)func main() { // Write to the trace file. f, _ := os.Create("trace.out") trace.Start(f) defer trace.Stop() // Set the target percentage for the garbage collector. Default is 100%. debug.SetGCPercent(100) // Task queue and result queue. taskQueue := make(chan int, NumTasks) resultQueue := make(chan int, NumTasks) // Start workers. var wg sync.WaitGroup wg.Add(NumWorkers) for i := 0; i < NumWorkers; i++ {  go worker(taskQueue, resultQueue, &wg) } // Send tasks to the queue. for i := 0; i < NumTasks; i++ {  taskQueue <- i } close(taskQueue) // Retrieve results from the queue. go func() {  wg.Wait()  close(resultQueue) }() // Process the results. for result := range resultQueue {  fmt.Println("Result:", result) } fmt.Println("Done!")}// Worker function.func worker(tasks <-chan int, results chan<- int, wg *sync.WaitGroup) { defer wg.Done() for task := range tasks {  result := performMemoryIntensiveTask(task)  results <- result }}// performMemoryIntensiveTask is a memory-intensive function.func performMemoryIntensiveTask(task int) int { // Create a large-sized slice. data := make([]int, MemoryIntense) for i := 0; i < MemoryIntense; i++ {  data[i] = i + task } // Latency imitation. time.Sleep(10 * time.Millisecond) // Calculate the result. result := 0 for _, value := range data {  result += value } return result}

跟蹤程序執行的結果被寫入文件trace.out:x5j28資訊網——每日最新資訊28at.com

// Writing to the trace file.f, _ := os.Create("trace.out")trace.Start(f)defer trace.Stop()

通過go tool trace,可以觀察堆大小的變化,并分析程序中垃圾收集器的行為。x5j28資訊網——每日最新資訊28at.com

請注意,go tool trace的精確細節和功能可能因go版本不同而有所差異,因此建議參考官方文檔,以獲取有關其在特定go版本中使用的詳細信息。x5j28資訊網——每日最新資訊28at.com

x5j28資訊網——每日最新資訊28at.com

GOGC的默認值

GOGC參數可以使用runtime/debug包中的debug.SetGCPercent進行設置,GOGC默認設置為100%。x5j28資訊網——每日最新資訊28at.com

用下面命令運行程序:x5j28資訊網——每日最新資訊28at.com

go run main.go

程序執行后,將會創建trace.out文件,可以使用go tool工具對其進行分析。要做到這一點,執行命令:x5j28資訊網——每日最新資訊28at.com

go tool trace trace.out

然后可以通過打開web瀏覽器并訪問http://127.0.0.1:54784/trace來查看基于web的跟蹤查看器。x5j28資訊網——每日最新資訊28at.com

x5j28資訊網——每日最新資訊28at.com

GOGC = 100x5j28資訊網——每日最新資訊28at.com

在"STATS"選項卡中,可以看到"Heap"字段,顯示了在應用程序執行期間堆大小的變化情況,圖中紅色區域表示堆占用的內存。x5j28資訊網——每日最新資訊28at.com

在"PROCS"選項卡中,"GC"(垃圾收集器)字段顯示的藍色列表示觸發垃圾收集器的時刻。x5j28資訊網——每日最新資訊28at.com

一旦新堆的大小達到活動堆大小的100%,就會觸發垃圾收集。例如,如果活躍堆大小為10 MB,則當當前堆大小達到10 MB時將觸發垃圾收集。x5j28資訊網——每日最新資訊28at.com

跟蹤所有垃圾收集調用使我們能夠確定垃圾收集器處于活動狀態的總時間。x5j28資訊網——每日最新資訊28at.com

x5j28資訊網——每日最新資訊28at.com

GOGC=100時的GC調用次數x5j28資訊網——每日最新資訊28at.com

示例中,當GOGC值為100時,將調用垃圾收集器16次,總執行時間為14 ms。x5j28資訊網——每日最新資訊28at.com

更頻繁的調用GC

如果我們將debug.SetGCPercent(10)設置為10%后運行代碼,將觀察到垃圾收集器調用的頻率更高?,F在,如果當前堆大小達到活躍堆大小的10%時,將觸發垃圾收集。x5j28資訊網——每日最新資訊28at.com

換句話說,如果活躍堆大小為10 MB,則當前堆大小達到1 MB時就將觸發垃圾收集。x5j28資訊網——每日最新資訊28at.com

x5j28資訊網——每日最新資訊28at.com

GOGC = 10x5j28資訊網——每日最新資訊28at.com

在本例中,垃圾收集器被調用了38次,總垃圾收集時間為28 ms。x5j28資訊網——每日最新資訊28at.com

x5j28資訊網——每日最新資訊28at.com

GOGC=10時的GC調用次數x5j28資訊網——每日最新資訊28at.com

可以觀察到,將GOGC設置為低于100%的值可以增加垃圾收集的頻率,可能導致CPU使用率增加并降低程序性能。x5j28資訊網——每日最新資訊28at.com

更少的調用GC

如果運行相同程序,但將debug.SetGCPercent(1000)設置為1000%,我們將得到以下結果:x5j28資訊網——每日最新資訊28at.com

x5j28資訊網——每日最新資訊28at.com

GOGC = 1000x5j28資訊網——每日最新資訊28at.com

可以看到,當前堆的大小一直在增長,直到達到活躍堆大小的1000%。換句話說,如果活躍堆大小為10 MB,則當前堆大小達到100 MB時將觸發垃圾收集。x5j28資訊網——每日最新資訊28at.com

x5j28資訊網——每日最新資訊28at.com

GOGC=1000時的GC調用次數x5j28資訊網——每日最新資訊28at.com

在當前情況下,垃圾收集器被調用一次并執行2毫秒。x5j28資訊網——每日最新資訊28at.com

關閉GC

還可以通過設置GOGC=off或調用debug.SetGCPercent(-1)來禁用垃圾收集。x5j28資訊網——每日最新資訊28at.com

下面是禁用垃圾收集器而不設置GOMEMLIMIT時堆的行為:x5j28資訊網——每日最新資訊28at.com

x5j28資訊網——每日最新資訊28at.com

當GC=off時,堆大小不斷增長。x5j28資訊網——每日最新資訊28at.com

可以看到,在關閉GC后,應用程序的堆大小一直在增長,直到程序執行為止。x5j28資訊網——每日最新資訊28at.com

堆占用多少內存?

在活躍堆的實際內存分配中,通常不像我們在trace中看到的那樣定期和可預測的工作。x5j28資訊網——每日最新資訊28at.com

活躍堆隨著每個垃圾收集周期動態變化,并且在某些條件下,其絕對值可能出現峰值。x5j28資訊網——每日最新資訊28at.com

例如,如果由于多個并行任務的重疊,活躍堆的大小可以增長到800 MB,那么只有在當前堆大小達到1.6 GB時才會觸發垃圾收集。x5j28資訊網——每日最新資訊28at.com

x5j28資訊網——每日最新資訊28at.com

現代開發通常在具有內存使用限制的容器中運行應用。因此,如果容器將內存限制設置為1 GB,并且總堆大小增加到1.6 GB,則容器將失效,并出現OOM(out of memory)錯誤。x5j28資訊網——每日最新資訊28at.com

讓我們模擬一下這種情況。例如,我們在內存限制為10 MB的容器中運行程序(僅用于測試目的)。Dockerfile:x5j28資訊網——每日最新資訊28at.com

FROM golang:latest as builderWORKDIR /srcCOPY . .RUN go env -w GO111MODULE=onRUN go mod vendorRUN CGO_ENABLED=0 GOOS=linux go build -mod=vendor -a -installsuffix cgo -o app ./cmd/FROM golang:latestWORKDIR /root/COPY --from=builder /src/app .EXPOSE 8080CMD ["./app"]

Docker-compose描述:x5j28資訊網——每日最新資訊28at.com

version: '3'services: my-app:   build:     context: .     dockerfile: Dockerfile   ports:     - 8080:8080   deploy:     resources:       limits:         memory: 10M

讓我們使用前面設置GOGC=1000%的代碼啟動容器。x5j28資訊網——每日最新資訊28at.com

可以使用以下命令運行容器:x5j28資訊網——每日最新資訊28at.com

docker-compose builddocker-compose up

幾秒鐘后,容器將崩潰,并產生與OOM相對應的錯誤。x5j28資訊網——每日最新資訊28at.com

exited with code 137

這種情況非常令人不快: GOGC只控制新堆的相對值,而容器有絕對限制。x5j28資訊網——每日最新資訊28at.com

如何避免OOM?

從1.19版本開始,在GOMEMLIMIT選項的幫助下,Golang引入了一個名為"軟內存管理"的特性,runtime/debug包中名為SetMemoryLimit的類似函數(可以閱讀48409-soft-memory-limit.md[6]了解有關此選項的一些有趣的設計細節)提供了相同的功能。x5j28資訊網——每日最新資訊28at.com

GOMEMLIMIT環境變量設置Go運行時可以使用的總體內存限制,例如: GOMEMLIMIT = 8MiB。要設置內存值,需要使用大小后綴,在本例中為8 MB。x5j28資訊網——每日最新資訊28at.com

讓我們啟動將GOMEMLIMIT境變量設置為8MiB的容器。為此,我們將環境變量添加到docker-compose文件中:x5j28資訊網——每日最新資訊28at.com

version: '3'services: my-app:    environment:      GOMEMLIMIT: "8MiB"   build:     context: .     dockerfile: Dockerfile   ports:     - 8080:8080   deploy:     resources:       limits:         memory: 10M

現在,當啟動容器時,程序運行沒有任何錯誤。該機制是專門為解決OOM問題而設計的。x5j28資訊網——每日最新資訊28at.com

這是因為啟用GOMEMLIMIT=8MiB后,會定期調用垃圾收集器,并將堆大小保持在一定限制內,結果就是會頻繁調用垃圾收集器以避免內存過載。x5j28資訊網——每日最新資訊28at.com

x5j28資訊網——每日最新資訊28at.com

運行垃圾收集器以使堆大小保持在一定的限制內。x5j28資訊網——每日最新資訊28at.com

成本是什么?

GOMEMLIMIT是強有力的工具,但也可能適得其反。x5j28資訊網——每日最新資訊28at.com

在上面的堆跟蹤圖中可以看到這種場景的一個示例。x5j28資訊網——每日最新資訊28at.com

當總內存大小由于活躍堆或持久程序泄漏的增長而接近GOMEMLIMIT時,將開始根據該限制不斷調用垃圾收集器。x5j28資訊網——每日最新資訊28at.com

由于頻繁調用垃圾收集器,應用程序的運行時可能會無限增加,從而消耗應用程序的CPU時間。x5j28資訊網——每日最新資訊28at.com

這種行為被稱為死亡螺旋[7],可能導致應用程序性能下降,與OOM錯誤不同,這種問題很難檢測和修復。x5j28資訊網——每日最新資訊28at.com

這正是GOMEMLIMIT機制作為軟限制起作用的原因。x5j28資訊網——每日最新資訊28at.com

Go不能100%保證GOMEMLIMIT指定的內存限制會被嚴格執行,而是會允許使用超出限制的內存,并防止頻繁調用垃圾收集器的情況。x5j28資訊網——每日最新資訊28at.com

為了實現這一點,需要對CPU使用設置限制。目前,這個限制被設置為所有處理器時間的50%,CPU窗口為2 * GOMAXPROCS秒。x5j28資訊網——每日最新資訊28at.com

這就是為什么我們不能完全避免OOM錯誤,而是會將其推遲到很久以后發生。x5j28資訊網——每日最新資訊28at.com

在哪里應用GOMEMLIMIT和GOGC

如果默認垃圾收集器設置在大多數情況下是足夠的,那么帶有GOMEMLIMIT的軟內存管理機制可以使我們避免不愉快的情況。x5j28資訊網——每日最新資訊28at.com

使用GOMEMLIMIT內存限制可能有用的例子:x5j28資訊網——每日最新資訊28at.com

  • 在內存有限的容器中運行應用程序時,最好將GOMEMLIMIT設置為保留5-10%的可用內存。
  • 在運行資源密集型庫或代碼時,對GOMEMLIMIT進行實時管理是有好處的。
  • 當在容器中以腳本形式運行應用程序時(意味著應用程序在一段時間內執行某些任務,然后終止),禁用垃圾收集器但設置GOMEMLIMIT可以提高性能并防止超出容器的資源限制。

避免使用GOMEMLIMIT的情況:x5j28資訊網——每日最新資訊28at.com

  • 當程序已經接近其環境的內存限制時,不要設置內存限制。
  • 在無法控制的執行環境中部署時,不要使用內存限制,特別是在程序的內存使用與其輸入數據成正比的情況下,例如CLI工具或桌面應用程序。

如上所述,通過深思熟慮的方法,我們可以管理程序中的微調設置,例如垃圾收集器和GOMEMLIMIT。然而,仔細考慮應用這些設置的策略無疑非常重要。x5j28資訊網——每日最新資訊28at.com

參考資料

  • [1]Memory Optimization and Garbage Collector Management in Go: https://betterprogramming.pub/memory-optimization-and-garbage-collector-management-in-go-71da4612a960
  • [2]A Guide to the Go Garbage Collector: https://tip.golang.org/doc/gc-guide
  • [3]mgc.go: https://go.dev/src/runtime/mgc.go
  • [4]malloc.go: https://go.dev/src/runtime/malloc.go
  • [5]mgc.go: https://go.dev/src/runtime/mgc.go
  • [6]48409-soft-memory-limit.md: https://github.com/golang/proposal/blob/master/design/48409-soft-memory-limit.md
  • [7]Soft Memory Limit Death Spirals: https://github.com/golang/proposal/blob/master/design/48409-soft-memory-limit.md#death-spirals

本文鏈接:http://m.www897cc.com/showinfo-26-61903-0.htmlGo 內存優化與垃圾收集

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 基于 Rust 的 linter 工具速度很快,但有嚴重缺陷...

下一篇: 高可靠的跨系統轉賬如何設計

標簽:
  • 熱門焦點
  • 盧偉冰長文解析K60至尊版 對Redmi有著里程碑式的意義

    在今天的Redmi后性能時代戰略發布會結束之后,Redmi總經理盧偉冰又帶來了一篇長文,詳解了為什么 Redmi 要開啟后性能時代?為什么選擇和 MediaTek、Pixelworks 深度合作?以及后性
  • 6月安卓手機性價比榜:Note 12 Turbo斷層式碾壓

    6月份有一個618,雖然這是京東周年慶的日子,但別的電商也都不約而同的跟進了,反正促銷沒壞處,廠商和用戶都能滿意。618期間一些產品也出現了歷史低價,那么各個價位段的產品性價比
  • 6月安卓手機性能榜:vivo/iQOO霸占旗艦排行榜前三

    2023年上半年已經正式過去了,我們也迎來了安兔兔V10版本,在新的驍龍8Gen3和天璣9300發布之前,性能榜的榜單大體會以驍龍8Gen2和天璣9200+為主,至于那顆3.36GHz的驍龍8Gen2領先
  • 一加首款折疊屏!一加Open渲染圖出爐:罕見單手可握小尺寸

    8月5日消息,此前就有爆料稱,一加首款折疊屏手機將會在第三季度上市,如今隨著時間臨近,新機的各種消息也開始浮出水面。據悉,這款新機將會被命名為&ldquo;On
  • K8S | Service服務發現

    一、背景在微服務架構中,這里以開發環境「Dev」為基礎來描述,在K8S集群中通常會開放:路由網關、注冊中心、配置中心等相關服務,可以被集群外部訪問;圖片對于測試「Tes」環境或者
  • 虛擬鍵盤 API 的妙用

    你是否在遇到過這樣的問題:移動設備上有一個固定元素,當激活虛擬鍵盤時,該元素被隱藏在了鍵盤下方?多年來,這一直是 Web 上的默認行為,在本文中,我們將探討這個問題、為什么會發生
  • 小米MIX Fold 3下月亮相:今年唯一無短板的全能折疊屏

    這段時間以來,包括三星、一加、榮耀等等有不少品牌旗下的最新折疊屏旗艦都有新的進展,其中榮耀、三星都已陸續發布了最新的折疊屏旗艦,尤其號榮耀Magi
  • 聯想小新Pad Pro 12.6將要推出,搭載高通驍龍 870 處理器

    聯想小新Pad Pro 12.6將于秋季新品會上推出,官方按照慣例直接在發布會前給出了機型的所有參數。聯想小新 Pad Pro 12.6 將搭載高通驍龍 870 處理器,重量為 5
  • 三翼鳥智能家居亮相電博會,讓用戶體驗更真實

    2021電博會在青島國際會展中心開幕中,三翼鳥直接把“家”搬到了現場,成為了展會的一大看點。這也是三翼鳥繼9月9日發布了行業首個一站式定制智慧家平臺后的
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
亚洲欧洲综合另类在线| 一区在线视频| 国产精品久久999| 国产日韩欧美在线播放不卡| 精品成人在线| 日韩一二三区视频| 亚洲欧美日韩国产精品| 久久久高清一区二区三区| 欧美xx69| 国产精品女主播在线观看| 韩国av一区二区三区四区| 亚洲人成免费| 午夜精品久久久久久久 | 久久五月天婷婷| 欧美精品在线免费| 国产精品一级久久久| 亚洲国产mv| 亚洲欧美综合一区| 欧美激情一区二区三区成人| 国产精品亚洲综合久久| 亚洲人成网站色ww在线| 欧美一区二区在线免费观看| 欧美激情第9页| 国产日韩欧美亚洲| 亚洲精品中文字| 久久久夜精品| 国产精品天天看| 亚洲精品久久久久| 久久久久国产精品人| 欧美性理论片在线观看片免费| 亚洲第一网站| 欧美亚洲综合在线| 欧美三级电影一区| 亚洲国产视频一区二区| 欧美在线视频一区| 欧美私人啪啪vps| 91久久久在线| 久久久久久91香蕉国产| 国产精品日韩一区二区三区| 9色porny自拍视频一区二区| 猛干欧美女孩| 国产在线播精品第三| 亚洲校园激情| 欧美日韩国产影片| 亚洲国产另类久久久精品极度| 欧美影院成年免费版| 欧美性淫爽ww久久久久无| 亚洲激情电影在线| 久久日韩粉嫩一区二区三区| 国产午夜精品全部视频播放 | 久久综合久久综合久久| 国产女主播视频一区二区| 一本色道久久综合狠狠躁篇怎么玩| 久久手机免费观看| 国产日韩欧美综合一区| 亚洲无人区一区| 欧美日韩国产精品 | 一区二区高清视频在线观看| 欧美国产日韩亚洲一区| 一区二区在线视频| 久久久久久有精品国产| 国产日韩欧美精品| 香蕉乱码成人久久天堂爱免费 | 久久精品亚洲一区| 国产欧美日韩精品专区| 亚洲自拍啪啪| 欧美视频在线观看免费| 日韩视频一区二区三区在线播放免费观看| 麻豆精品传媒视频| 伊人精品在线| 久久中文精品| 一区二区三区在线观看欧美| 久久精品视频免费播放| 国产午夜精品美女视频明星a级 | 男女激情久久| 亚洲国产精品成人| 免费高清在线视频一区·| 在线观看亚洲| 免费日韩精品中文字幕视频在线| 在线观看视频免费一区二区三区| 久久综合网hezyo| 亚洲第一精品福利| 米奇777在线欧美播放| 影音先锋日韩精品| 蜜臀av国产精品久久久久| 1024亚洲| 欧美激情视频在线免费观看 欧美视频免费一| 亚洲激情社区| 欧美日韩大片| 在线视频欧美日韩| 国产精品久久久免费| 亚洲一区二区三区精品视频| 国产精品成人一区| 亚洲欧美日韩在线| 国产亚洲va综合人人澡精品| 久久精品免费观看| 精品成人一区二区三区四区| 欧美成人精品一区| 9久re热视频在线精品| 国产精品欧美日韩| 久久精品久久99精品久久| 亚洲高清视频在线| 欧美日韩色婷婷| 午夜天堂精品久久久久| 韩国视频理论视频久久| 欧美成人在线影院| 亚洲一区二区三区777| 国产丝袜一区二区三区| 麻豆精品在线视频| 夜夜爽www精品| 国产欧美一区二区三区另类精品| 久久久水蜜桃av免费网站| 亚洲欧洲一区二区在线播放| 欧美午夜无遮挡| 亚洲欧洲av一区二区三区久久| 韩日欧美一区二区| 欧美精品一区二区三区一线天视频| 亚洲视屏在线播放| 国产综合色一区二区三区 | 国产女优一区| 免费亚洲网站| 亚洲一区二区精品视频| 激情综合在线| 欧美色欧美亚洲高清在线视频| 欧美在线亚洲综合一区| 亚洲激情一区二区三区| 国产精品美女一区二区在线观看| 久久久人成影片一区二区三区| 99这里只有久久精品视频| 国产欧美va欧美va香蕉在| 免费的成人av| 亚洲欧美日本视频在线观看| 亚洲福利久久| 国产精品视频网站| 欧美~级网站不卡| 亚洲欧美在线免费观看| 亚洲片在线资源| 国产嫩草影院久久久久 | 国产精品夫妻自拍| 美女视频一区免费观看| 亚洲欧美激情一区二区| 亚洲国产欧洲综合997久久| 国产精品久久久久久一区二区三区| 久久一区二区三区av| 亚洲欧美精品伊人久久| 亚洲日本激情| 韩国三级在线一区| 国产精品欧美在线| 欧美经典一区二区| 久久精品国产77777蜜臀| 一区二区三区日韩欧美| 亚洲第一黄色网| 国产日韩一区欧美| 欧美日韩中文字幕在线| 美国十次成人| 久久精品日产第一区二区| 亚洲无毛电影| 日韩午夜免费视频| 1024日韩| 精品成人乱色一区二区| 国产欧美丝祙| 国产精品国产三级国产普通话三级 | 亚洲自拍另类| 亚洲日韩欧美视频| 激情文学一区| 国产免费成人| 欧美午夜激情小视频| 欧美va亚洲va香蕉在线| 久久久青草青青国产亚洲免观| 午夜亚洲性色福利视频| 一区二区三区视频在线观看| 91久久久一线二线三线品牌| 尤物yw午夜国产精品视频| 国产欧美精品日韩| 国产精品久久久久久久久久久久久久| 欧美精品一区二区精品网| 男女精品网站| 久久综合久色欧美综合狠狠| 久久精品天堂| 午夜久久久久| 亚洲综合好骚| 亚洲一区二区毛片| 一区电影在线观看| 亚洲精品欧美专区| 亚洲国产va精品久久久不卡综合| 一区二区在线视频| 激情一区二区三区| 国内精品写真在线观看| 国产日韩欧美中文在线播放| 国产色综合久久| 国产欧美高清| 国产亚洲午夜| 国产一区二区高清| 国产一区二区三区高清在线观看| 国产欧美日韩综合精品二区| 国产精品私房写真福利视频| 国产精品入口| 国产亚洲精品久久飘花 | 亚洲免费影视| 欧美一区二区在线| 久久激情五月激情| 久久久亚洲精品一区二区三区| 久久综合九色综合网站| 麻豆成人精品|