Analysis of the common.URL memory leak #2764
Replies: 5 comments 1 reply
-
Another good tool is pyroscope Pyroscope 是一个开源的性能分析工具,用于帮助开发者收集、查看和分析应用程序的性能数据(如 CPU 使用率、内存消耗等)。它通过采样的方式,收集程序的性能数据并提供可视化界面,以便开发者查找性能瓶颈,优化代码。 Pyroscope 支持多种编程语言,包括 Go、Java、Python 等,通常用于生产环境中的应用程序性能监控。 安装 Pyroscope首先,需要在本地或服务器上安装 Pyroscope。它有多种部署方式,包括 Docker、Kubernetes、以及本地安装。 1. 使用 Docker 安装 Pyroscopedocker run -d -p 4040:4040 pyroscope/pyroscope:latest 这将会启动一个容器,并在本地的 4040 端口上暴露 Pyroscope 的 Web 界面。 2. 使用 Homebrew(Mac)安装brew install pyroscope-io/pyroscope/pyroscope 3. 从源代码安装如果你更喜欢从源代码安装,可以按照 Pyroscope GitHub 仓库上的 安装指南 进行操作。 配置和使用 Pyroscope安装 Pyroscope 后,你需要将其集成到你的应用程序中来收集性能数据。 1. 启动 Pyroscope 服务Pyroscope 有一个 Web 界面,可以用来查看和分析性能数据。启动 Pyroscope 后,访问 http://localhost:4040 来查看性能分析数据。 2. 在应用中集成 Pyroscope 客户端Pyroscope 提供了多个客户端库,可以帮助你将性能数据发送到 Pyroscope 服务。 Go 示例:import (
"github.com/pyroscope-io/pyroscope"
)
func main() {
// 设置 Pyroscope 客户端
pyroscope.Start(pyroscope.Config{
ApplicationName: "your-app",
ServerAddress: "http://localhost:4040", // Pyroscope 服务器地址
})
// Your application logic here
} Python 示例:import pyroscope
# Set up Pyroscope client
pyroscope.configure(
application_name="your-app",
server_address="http://localhost:4040", # Pyroscope server address
)
# Your application logic here 通过这种方式,Pyroscope 客户端将会定期发送性能数据到 Pyroscope 服务器。 3. 查看和分析性能数据访问 Pyroscope 的 Web 界面(默认地址是
你可以选择不同的时间窗口、查看不同的应用等,来详细分析你的应用程序性能。 Pyroscope 的特点
进阶使用
总结Pyroscope 是一个非常实用的性能分析工具,特别适合开发者在生产环境中进行应用性能监控。通过简单的安装和配置,你可以在你的应用中集成 Pyroscope,收集实时的性能数据,并通过 Pyroscope 的 Web 界面进行可视化分析,帮助你快速识别并解决性能瓶颈。 |
Beta Was this translation helpful? Give feedback.
-
在 Go 程序中,内存泄漏是一个常见且严重的问题,它会导致程序内存消耗不断增加,最终可能引起系统崩溃或严重性能下降。使用 Pyroscope 进行内存泄漏检测可以帮助你实时监控程序的内存使用情况,发现潜在的内存泄漏问题。 下面是如何使用 Pyroscope 来检测 Go 程序中的内存泄漏: 1. 安装并启动 Pyroscope首先,确保 Pyroscope 已经安装并启动。在本地测试时,可以通过 Docker 启动 Pyroscope 服务: docker run -d -p 4040:4040 pyroscope/pyroscope:latest 这将会在 2. 集成 Pyroscope 到你的 Go 程序要在 Go 程序中集成 Pyroscope 进行内存分析,你需要使用 Pyroscope Go 客户端。按照以下步骤操作: 安装 Pyroscope Go 客户端通过 go get github.com/pyroscope-io/pyroscope 配置 Pyroscope 客户端在你的 Go 程序中引入 Pyroscope 库,并进行配置,启用内存采样。 package main
import (
"github.com/pyroscope-io/pyroscope"
"log"
"time"
)
func main() {
// 配置 Pyroscope 客户端,指定应用名称和 Pyroscope 服务器地址
err := pyroscope.Start(pyroscope.Config{
ApplicationName: "your-go-app",
ServerAddress: "http://localhost:4040", // Pyroscope 服务器地址
})
if err != nil {
log.Fatalf("Error starting pyroscope: %v", err)
}
// 模拟内存使用,可能引发内存泄漏
for {
leakMemory()
time.Sleep(5 * time.Second)
}
}
// 模拟内存泄漏的函数
func leakMemory() {
// 创建一个大的数组或对象,模拟内存泄漏
_ = make([]byte, 10*1024*1024) // 分配 10MB 内存
} 代码说明:
3. 查看内存分析数据在程序运行时,Pyroscope 会定期采样内存使用情况。你可以通过访问 Pyroscope 的 Web 界面(默认地址为 在 Pyroscope Web 界面中,你会看到以下内容:
4. 分析内存泄漏
5. 使用 Pyroscope 收集更多内存信息除了使用 Pyroscope 进行基础的内存分析,你还可以利用 Pyroscope 来收集更多的内存相关数据: 启用内存分析Pyroscope 允许你分析堆、栈和内存分配等信息。你可以在配置文件中启用内存采样: err := pyroscope.Start(pyroscope.Config{
ApplicationName: "your-go-app",
ServerAddress: "http://localhost:4040", // Pyroscope 服务器地址
ProfileTypes: []pyroscope.ProfileType{
pyroscope.TypeCPU,
pyroscope.TypeAllocations,
},
}) 在这个配置中, 6. 其他注意事项
总结
|
Beta Was this translation helpful? Give feedback.
-
1. 安装
|
Beta Was this translation helpful? Give feedback.
-
My question is, is this simulation scenario reasonable? are there any other scenarios that can reproduce the problem? |
Beta Was this translation helpful? Give feedback.
-
如果在执行泛化调用场景下复现时出现以下如图所示的错误(原因是不支持无参数的泛化调用) 参考这个pr apache/dubbo-go-samples#790 |
Beta Was this translation helpful? Give feedback.
-
Background
Based on the following issues
#2031
#2339
#2701
we can see that
common.URL
has a memory leak problem. However, none of these issues mentioned the minimum steps to reproduce. Therefore, I tried to reproduce the cause of the memory leak in a generic-call scenario (the use case where I found the memory leak myself). The simulation scenario here is to make generic-call to different providers(the same providerorg.apache.dubbo.samples.UserProvider
is used in the client code for convenience.) multiple times (similar to the gateway scenario, generic-call to multiple providers as a proxy). The following are the steps to reproduce and how to use the [goref](https://github.com/cloudwego/goref) tool for memory leak analysis.Reproduce the memory leak of
common.URL
and usegoref
for heap object reference analysis1.install goref
Make sure your go version is >= go1.21
2.start docker
In dubbo-go-samples root directory, all related test is based on dubbo-go-samples;
3.start server
for example
4.edit client code
based on [go ref test samples](https://github.com/cloudwego/goref/blob/main/testdata/mockleak/main.go)
for example
cd ./compatibility/generic/default/go-client/cmd
import proof
start to listen 6060 port, add these lines in the begining of client.go/main()
modify the code to simulate multiple generic-calls, i simulated a four-minute generic-calls with the following code
Add script gif_test.sh
run this script and wait for terminal output (maybe a few minutes)
successfully output to `grf.out`
5.Open grf.out file
install
graphviz
, and then6.Analysis flame graph
click this to get detailed heap object reference information
We can find that it is mainly
baseinvoker
that holds theseurl
objects, which eventually leads to memory leaks. Since dubbo-go-samples is using thedubbo.apache.org/dubbo-go/v3 v3.2.0-rc1
version, and the related PR to fix this momery leak issue is #2726 which has not been released yet. To verify whether this PR fixes the memory leak problem, i replaced the file to the local file(which keep consistent with the dubbo-go/develop branch);and retest the above scenario, the final result is
we can see that there is no memory leak of
common.URL
;Welcome any discussion
Beta Was this translation helpful? Give feedback.
All reactions