相关疑难解决方法(0)

如何在Golang中实现内存池

我在Go中实现了一个HTTP服务器.

对于每个请求,我需要为特定的结构创建数百个对象,我有~10个这样的结构.因此,根据Go实现完成请求后,它将被垃圾收集.

因此,对于每个请求,将分配和释放大量内存.

相反,我想实现内存池以提高分配端和GC端的性能

在请求开始时,我将从池中取出并在请求提供后将其放回

从池实现方面

  1. 如何分配和释放特定类型结构的内存?
  2. 如何跟踪这个记忆分配的信息,而其他信息不是?

在内存分配和释放的情况下,还有其他任何提高性能的建议吗?

memory-management go

12
推荐指数
2
解决办法
8346
查看次数

Go Webserver的流程管理

我是一名新的Go程序员,来自Web应用程序和服务开发领域.道歉这是一个关于dep deprp的问题,但我的谷歌搜索答案还没有找到任何答案.此外,这是边缘服务器故障区域,但由于我对API /编程接口更感兴趣,我在这里问.

我使用net/http软件包的内置Web服务器编写了一个小程序.我正准备部署到生产环境,但我对模型Go Go的Web服务器以及我应该如何部署的过程有点不清楚.

具体来说 - 在我习惯的环境(PHP,Ruby,Python)中,我们在应用程序前面有一个Web服务器(Apache,Nginx等),我们将这些Web服务器配置为使用一定数量的工作进程/线程,并配置每个线程应处理的单个HTTP(S)连接数.

我无法找到有关Go的Web服务器如何处理此信息的信息,或者有关如何扩展/规划Go Web服务器规模的实用信息.

即 - 如果我有一个简单的程序运行,准备处理HTTP请求

func main() {
   http.HandleFunc("/", processRequest)
   http.ListenAndServe(":8000", nil)    
}
Run Code Online (Sandbox Code Playgroud)

HandleFunc一次会尝试处理多少个连接?或者它会在连接打开时开始阻塞,并且只在连接关闭后才提供下一个连接?

或者我应该不担心这一点,并把所有东西都塞进一个常规程序?但是,如果我这样做,我如何防止系统被太多执行线程陷入困境?

我基本上是想要

  1. 了解go web服务器的进程模式
  2. 找到调整它的内置功能,和/或任何标准包使用者

就像我说的,我很新,所以如果我完全错过了这方面的情节,请告诉我!

http scale go net-http

10
推荐指数
2
解决办法
1907
查看次数

这是Go中惯用的工作线程池吗?

我正在尝试用goroutines编写一个简单的工作池.

  • 我写的代码是惯用的吗?如果没有,那么应该改变什么呢?
  • 我希望能够将最大工作线程数设置为5并阻塞,直到工作人员可用,如果所有5个工作线都忙.我如何将此扩展到最多只有5名工作人员?我是否会产生静态的5 goroutines,然后分别给它们work_channel

码:

package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

func worker(id string, work string, o chan string, wg *sync.WaitGroup) {
    defer wg.Done()
    sleepMs := rand.Intn(1000)
    fmt.Printf("worker '%s' received: '%s', sleep %dms\n", id, work, sleepMs)
    time.Sleep(time.Duration(sleepMs) * time.Millisecond)
    o <- work + fmt.Sprintf("-%dms", sleepMs)
}

func main() {
    var work_channel = make(chan string)
    var results_channel = make(chan string)

    // create goroutine per item in work_channel
    go func() {
        var c = 0
        var wg …
Run Code Online (Sandbox Code Playgroud)

concurrency multithreading go goroutine

10
推荐指数
1
解决办法
2407
查看次数

FreeOSMemory()正在制作中

我在一个包含tcp服务器的包中使用goroutine.大部分时间的响应非常繁重,但是当例程结束时,它不会从内存中清除.

func Handle() {
    service := ":7777"
    tcpAddr, err := net.ResolveTCPAddr("tcp4", service)
    checkError(err)
    listener, err := net.ListenTCP("tcp", tcpAddr)
    checkError(err)
    defer listener.Close()

    for {
        conn, err := listener.Accept()
        checkError(err)
        go handleRequest(conn, db)

    }
}

func handleRequest(conn net.Conn, db *sql.DB) {
    message := make([]byte, 0, 4096)
    tmp := make([]byte, 256)
    n, err := conn.Read(tmp)
    if err != nil {
        if err != io.EOF {
            fmt.Println("read error:", err)
        }
    }
    message = append(message, tmp[:n]...)
    fmt.Println("Message Received:", string(message))
    // do something to get resp …
Run Code Online (Sandbox Code Playgroud)

garbage-collection memory-leaks go

6
推荐指数
1
解决办法
2690
查看次数

一旦被bytes.Buffer占用就无法释放内存

我收到compressedbytes类型为[] byte 的压缩ASCII文本字节.我面临的问题是,以下过程占用了大量内存,这些内存在函数到达其结束后未被释放,并且在程序的整个运行时期间仍然被占用.

    b := bytes.NewReader(compressedbytes)
    r, err := zlib.NewReader(b)
    if err != nil {
        panic(err)
    }
    cleartext, err = ioutil.ReadAll(r)
    if err != nil {
        panic(err)
    }
Run Code Online (Sandbox Code Playgroud)

我注意到使用的类型是bytes.Buffer,这种类型具有Reset()Truncate()函数,但它们都不允许释放曾经占用的内存.

文档Reset()状态如下:

重置将缓冲区重置为空,但它会保留底层存储以供将来的写入使用.重置与截断(0)相同.

如何取消缓冲区并再次释放内存?我的程序在运行期间需要大约50MB的内存,需要2小时.当我导入zlib压缩的字符串时,程序需要200 MB的内存.

谢谢你的帮助.

===更新

我甚至为解压缩创建了一个单独的函数,并runtime.GC()在程序从该函数返回后手动调用垃圾收集器,但没有成功.

// unpack decompresses zlib compressed bytes
func unpack(packedData []byte) []byte {
    b := bytes.NewReader(packedData)
    r, err := zlib.NewReader(b)
    if err != nil {
        panic(err)
    }
    cleartext, err := ioutil.ReadAll(r)
    if …
Run Code Online (Sandbox Code Playgroud)

memory buffer zlib go

4
推荐指数
1
解决办法
8848
查看次数

Golang:使用net/http在分配的堆中不断增加(内存泄漏),

我已经使用golang来使用golang反向代理构建应用程序api网关,但是我能够看到逐渐增加内存并且我试图分析,这里是启动后几小时内的图形.这有什么不对或预期.所有的分配都来自内置软件包和negroni mux.

在此输入图像描述

去常规的数量

memory-leaks memory-management go

0
推荐指数
1
解决办法
1825
查看次数

Go的垃圾收集器未在正确的时间释放内存

我编写了一个简单的http golang网络服务器来测试Go垃圾回收(释放无法访问的指针的内存),但是在strees测试中,我知道它消耗了过多的内存。

根据一些问题/答案,我发现Golang会自动进行垃圾回收,管理额外的内存本身,并且不会立即将内存退回给OS。一些结果:

  • 网络服务器在大约5分钟后释放ram。

  • 网络服务器会消耗ram直到达到特定级别并且请求更多连接不会获得更多内存(在我的情况下约为4GB)

消耗4GB的内存并不酷!因此,我在代码中添加了Goroutine,以将额外的内存返回给OS。

代码:

type t struct{
    a       []string
    b       map[string]string
}
var x t = t{
    a:  []string{"1","2"},
    b:  make(map[string]string),
}

func handler(w http.ResponseWriter, r *http.Request) {
    x := &t{}
    fmt.Fprintf(w, "pong", r.URL.Path[1:])
}

func main() {
    http.HandleFunc("/ping", handler)
    go func(){
        for {
            time.Sleep(10 * time.Second)
            fmt.Println("Free up memory...")
            debug.FreeOSMemory() 
        }

    }()
    log.Fatal(http.ListenAndServe(":8080", nil))
}
Run Code Online (Sandbox Code Playgroud)

对于压力测试,我使用Apache Bench

ab -c 100 -n 400000 http://127.0.0.1:8080/ping
Run Code Online (Sandbox Code Playgroud)

我连续10次以上运行命令以检查ram的使用情况。它工作得很好,但是问题是,是否有任何标准方法可以更好地释放内存!

我知道在某些情况下,Go可以自行管理内存,而不是从操作系统中重复释放和获取内存,这是一件好事。但是在我的情况下,延迟5分钟对于释放内存非常重要。

garbage-collection go

0
推荐指数
1
解决办法
1442
查看次数