[Golang] timer可能造成的内存泄漏

背景
前两天,跟一位学长交流Golang;然后,他突然问我:你知道timer可能造成内存泄漏嘛? 当时,甚是一脸懵逼,毕竟之前写的Agent测了好久,都没发现这个问题啊。今天,就索性了解了下。这里先说下结论,timer的误用可能造成某些等待timer的Goroutine无法正常退出,导致资源无法释放;(ps. 虽然的确算是内存泄漏,但是对于我这种写C出身的人来说,感觉还是怪怪的)

接下来进入正题,让我们先看一段代码;
这段代码的意图是,协程在timer.Stop()调用后能够继续执行从而退出;
但是,实际的效果呢? 我们没有看到任何输出提示;

那是为什么呢?这当中核心的原因就是,timer.Stop() 这个接口从设计的时候就设计成了并不去关闭Channel;既然不关闭Chan,那么本例中的协程也就无法继续执行,从而退出了;

package main

import (
    "time"
    "fmt"
)

func main() {
    timer := time.NewTimer(3 * time.Second)

    go func() {
        <-timer.C
        fmt.Println("Timer has expired.")
    }()

    timer.Stop()
    time.Sleep(60 * time.Second)
}

作为一种修复手段,

package main

import (
    "time"
    "fmt"
)


func main() {
    timer := time.NewTimer(3 * time.Second)

    go func() {
        <-timer.C
        fmt.Println("Timer has expired.")
    }()

    //timer.Stop()
    timer.Reset(0  * time.Second)
    time.Sleep(60 * time.Second)
}


————————————————
版权声明:本文为CSDN博主「sai_j」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sai_j/article/details/82780081

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Go 中使用 syscall 库来读取内存需要使用 syscall.PtracePeekData() 函数。这个函数需要传入两个参数,一个是进程 ID,另一个是内存地址。它返回一个字节数组和一个错误信息。示例代码如下: ``` package main import ( "fmt" "syscall" ) func main() { data, err := syscall.PtracePeekData(pid, addr) if err != nil { fmt.Println(err) } fmt.Println(data) } ``` 其中 pid 是要读取内存的进程 ID,addr 是要读取内存的地址。 需要注意的是,在 Go 中读取其他进程的内存需要获得相应的权限,可以在程序启动时使用 syscall.PtraceAttach() 函数附加到目标进程上。 ### 回答2: 在Golang中,可以使用syscall包中的ReadProcessMemory函数来读取其他进程的内存。该函数需要传入需要读取内存的进程的句柄、要读取的内存地址以及一个指向要保存读取结果的缓冲区的指针。 首先,需要使用syscall包中的OpenProcess函数打开要读取内存的进程。OpenProcess函数接受一个进程ID和访问权限参数,并返回一个进程句柄。可以通过进程ID使用os.FindProcess函数获取进程句柄。然后,将得到的进程句柄传递给ReadProcessMemory函数。 接下来,需要通过syscall包中的VirtualQueryEx函数获取要读取的内存的一些基本信息,例如内存所在的模块、保护方式等。这些信息包含在MEMORY_BASIC_INFORMATION结构体中。使用VirtualQueryEx函数时,需要传入进程句柄和要查询的内存地址。函数在指定地址处返回一个MEMORY_BASIC_INFORMATION结构体的指针。 然后,可以通过ReadProcessMemory函数读取内存。该函数需要传入进程句柄、要读取的内存地址以及一个指向要保存读取结果的缓冲区的指针。可以根据前面获取到的MEMORY_BASIC_INFORMATION结构体的信息,确定要读取的内存地址范围和大小,然后将这些信息传递给ReadProcessMemory函数。成功读取内存后,可以将缓冲区中的数据转换为所需的数据类型。 最后,需要使用syscall包中的CloseHandle函数关闭打开的进程句柄,以释放资源。 需要注意的是,使用syscall包中的函数需要在适当的操作系统上运行,并且需要有足够的权限来访问指定的进程内存。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值