当前位置: 首页 > 面试题库 >

Go http标准库中的内存泄漏?

夏侯腾
2023-03-14
问题内容

让Go二进制程序实现http服务器:

package main

import (
    "net/http"
)

func main() {
    http.ListenAndServe(":8080", nil)
}

它将以大约850 kb的内存开始。通过网络浏览器发送一些请求。观察它很快上升到1 mb。如果您等待,您将看到它永远不会失败。现在,使用Apache
Bench对其进行锤打(使用下面的脚本),并查看您的内存使用量在不断增加。一段时间后,它将最终稳定在8.2 MB左右。

编辑:它似乎并没有在8.2处停止,而是明显放慢了速度。目前为9.2,并且仍在上升。

简而言之,为什么会这样?我使用了这个shell脚本:

while [ true ]
do
    ab -n 1000 -c 100 http://127.0.0.1:8080/
    sleep 1
end

在尝试深入了解这一点的同时,我尝试调整设置。我尝试关闭使用r.Close = true以防止保持活动状态。似乎没有任何作用。

我最初是在尝试确定正在编写的程序中是否存在内存泄漏时才发现的。它有很多http处理程序和I /
O调用。检查完所有数据库连接后,我继续看到它的内存使用量增加。我的程序稳定在 433 MB 左右。

这是Goenv的输出:

GOARCH="amd64"
GOBIN=""
GOCHAR="6"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/mark/Documents/Programming/Go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
TERM="dumb"
CC="clang"
GOGCCFLAGS="-g -O2 -fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fno-common"
CXX="clang++"
CGO_ENABLED="1"

问题答案:

pprof您在注释中提供的堆中,看来您正在通过gorilla/sessionsgorilla/context(将近400MB)泄漏内存。

请参阅以下ML线程:[https]( https://groups.google.com/forum/#!msg/gorilla-
web/clJfCzenuWY/N_Xj9-5Lk6wJ) :
[//groups.google.com/forum/#!]( https://groups.google.com/forum/#!msg/gorilla-
web/clJfCzenuWY/N_Xj9-5Lk6wJ) msg/gorilla-web/clJfCzenuWY/
[N_Xj9-5Lk6wJ]( https://groups.google.com/forum/#!msg/gorilla-
web/clJfCzenuWY/N_Xj9-5Lk6wJ)和此GH问题: https
//github.com/gorilla/sessions/issues/
15

这是一个泄漏速度非常快的版本:

package main

import (
    "fmt"
    // "github.com/gorilla/context"
    "github.com/gorilla/sessions"
    "net/http"
)

var (
    cookieStore = sessions.NewCookieStore([]byte("cookie-secret"))
)

func main() {
    http.HandleFunc("/", defaultHandler)
    http.ListenAndServe(":8080", nil)
}

func defaultHandler(w http.ResponseWriter, r *http.Request) {
    cookieStore.Get(r, "leak-test")
    fmt.Fprint(w, "Hi there")
}

这是一个清理并具有相对静态的RSS的示例

package main

import (
    "fmt"
    "github.com/gorilla/context"
    "github.com/gorilla/sessions"
    "net/http"
)

var (
    cookieStore = sessions.NewCookieStore([]byte("cookie-secret"))
)

func main() {
    http.HandleFunc("/", defaultHandler)
    http.ListenAndServe(":8080", context.ClearHandler(http.DefaultServeMux))
}

func defaultHandler(w http.ResponseWriter, r *http.Request) {
    cookieStore.Get(r, "leak-test")
    fmt.Fprint(w, "Hi there")
}


 类似资料:
  • 问题内容: 我想“ndb”库有内存泄漏,但我找不到在哪里。 有没有办法避免下面描述的问题? 你有更准确的测试方法来找出问题所在吗 是? 我就是这样再现这个问题的: 我用2个文件创建了一个极简的Google应用程序引擎。 : : 我上传了一个名为“/create”的应用程序。 之后,每次对的调用都会增加实例使用的内存。直到 由于错误“超出了128 MB的软专用内存限制,它将停止 总共为5个请求提供服

  • 我尝试用一个大表(大约一万条记录)中的记录填充JdbcRowSet。我尝试了两个变体(参见下面的代码): 创建连接对象,使用JdbcRowSetImpl(connection)实例化,在循环中执行查询。 使用JdbcRowSetImpl(DriverManager.GetConnection(“jdbc:....”)实例化,在循环中执行查询。 第一个变体会导致内存泄漏,直到堆满为止。第二个变体没有

  • 我有一个在Tomcat7上运行的web应用程序的问题。 当我尝试重新启动web应用程序时,我在servlet内部创建的线程打开的端口仍然是打开的。 “http-bio-8080-acceptor-0”后台进程prio=10 tid=0x00007F4ED4206000 nid=0x71f0 runnable[0x00007F4ECC78F000]java.lang.thread.state:run

  • 我在Tomcat中得到了threadlocal内存泄漏错误,我正在使用ThreadPool,但在我的WebApp中没有threadlocal的实现。 严重:web应用程序[/mywebapp]创建了一个ThreadLocal,其键类型为[org.a pache.http.impl.cookie.dateformatholder$1](值为[org.apache.http.imp l.cookie.

  • gohttp 是一个 http 的文件服务器。因为是用 go 语言写的,所以加了一个 go 的抬头。之所以用 go 是因为发布起来是一个二进制文件,不同的平台都可以用,而且没有依赖问题,且稳定性也很好。 pjax简称页面ajax技术 在gohttp进行目录却换的时候,你会看到地址栏在变,但是页面却是局部刷新的。 各种文件的预览功能 所有常见的代码都可以直接在gohttp下预览,如果你用的是chro

  • 问题内容: 我正在阅读android docs http://developer.android.com/reference/com/google/android/gms/maps/MapFragment.html ,我碰到了这句话: 从GoogleMap获得的所有对象都与该视图相关联。重要的是不要在视图的生命周期之内保留对象(例如Marker)。否则将导致内存泄漏,因为无法释放视图。 我不完全了