草庐IT

go - 紧密环路泄漏 Reader

coder 2023-07-02 原文

我认为以下代码泄漏严重。并对其进行分析,我怀疑 defer r.Close() 从未被调用过。

有没有更好的方法在这里使用 Reader 和 gzip?

// Read client data from channel
func (c *Client) listen() {
    timeoutDuration := 30 * time.Second

    reader := bufio.NewReader(c.conn)

    clientBuffer := new(bytes.Buffer)

    for {
        c.conn.SetReadDeadline(time.Now().Add(timeoutDuration))

        byte, err := reader.ReadByte()

        if err != nil {
            c.conn.Close()
            c.server.onClientConnectionClosed(c, err)
            return
        }

        clientBuffer.WriteByte(byte)
        packet := popPacketFromBuffer(clientBuffer)

        if packet != nil {
            packetBuffer := bytes.NewBuffer(packet)

            r, _ := gzip.NewReader(packetBuffer)
            defer r.Close()

            b, err := ioutil.ReadAll(r)
            if err != nil {
                log.Fatal(err)
            }

            c.server.onNewMessage(c, b)
        }

    }
}

最佳答案

你的问题是 defer 函数只在函数结束时被调用。不是循环。所以,是的,他们很可能会继续营业。

一种方法是将您的紧密循环封装到一个函数中。

func uncompress(packet []byte) ([]byte, error) {
    r, _ := gzip.NewReader(bytes.NewBuffer(packet))
    defer r.Close()
    return ioutil.ReadAll(r)
}

// Read client data from channel
func (c *Client) listen() {
    /* … */

    for {
        /* … */

        if packet != nil {
            b, err := uncompress(packet)
            if err != nil {
                log.Fatal(err)
            }
            c.server.onNewMessage(c, b)
        }

    }
}

另一种方法是展开延迟调用并手动执行。

// Read client data from channel
func (c *Client) listen() {
    /* … */

    for {
        /* … */

        if packet != nil {
            r, _ := gzip.NewReader(bytes.NewBuffer(packet))
            b, err := ioutil.ReadAll(r)
            if err != nil {
                log.Fatal(err)
            }
            r.Close()
            c.server.onNewMessage(c, b)
        }

    }
}

关于go - 紧密环路泄漏 Reader,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41639955/

有关go - 紧密环路泄漏 Reader的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. 键删除后 ruby​​ 哈希内存泄漏 - 2

    你好,我无法成功如何在散列中删除key后释放内存。当我从哈希中删除键时,内存不会释放,也不会在手动调用GC.start后释放。当从Hash中删除键并且这些对象在某处泄漏时,这是预期的行为还是GC不释放内存?如何在Ruby中删除Hash中的键并在内存中取消分配它?例子:irb(main):001:0>`ps-orss=-p#{Process.pid}`.to_i=>4748irb(main):002:0>a={}=>{}irb(main):003:0>1000000.times{|i|a[i]="test#{i}"}=>1000000irb(main):004:0>`ps-orss=-p

  3. ruby-on-rails - Textmate 'Go to symbol' 相当于 Vim - 2

    在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol

  4. ruby - rails 3.0.7 内存泄漏 - 2

    我的两个不同的Rails应用程序的内存有一些奇怪的问题。这两个应用程序都使用rails3.0.7。每个Controller请求分配20-30-50MB的内存。在生产模式下,这个数量减少到5-10。但这是同样的事情。这是两个应用程序使用的gem列表:gem'pg'gem'haml'gem'sass'gem'devise'gem'simple_form'gem'state_machine'gem"globalize3","0.1.0.beta"gem"easy_globalize3_accessors"gem'paperclip'gem'andand'关闭所有这些gem不会给我任何结果。我

  5. 如果使用 <<,Ruby attr_reader 允许修改字符串变量 - 2

    遇到一些奇怪的行为,想知道是否有其他人可以确认我所看到的。假设您创建了一个带有成员变量的类,并允许使用attr_reader读取它。classTestClassattr_reader:valdefinitialize(value)@val=valueendend现在当我执行以下操作时,它似乎修改了@val的值,即使我只授予它读取权限。test=TestClass.new('hello')putstest.valtest.val返回hellohelloworld这只是我在irb中进行的一些测试的结果,所以不确定是否总是如此 最佳答案

  6. ruby-on-rails - 升级到 OSX Lion 后 ruby​​ 进程内存泄漏 - 2

    几周前我升级到Lion,它完全被RubyonRails环境搞砸了。我已经安装了RVM,不同的ruby​​版本,但似乎找不到解决方案……我认为这是我升级到Lion所能做的最糟糕的决定之一。它只会给我带来问题。无论如何,我已经意识到渲染我的应用程序页面(它在已部署的服务器上以及在其他机器上本地运行良好)会增加20-30mb的ruby​​进程内存,这有点疯狂。所以你可以想象一下,过了一会儿,我的ruby​​进程使用了​​2gb的内存,我的电脑就不能用了。我见过很多人在升级到Lion时遇到问题,但我一直无法为我的案例找到解决方案。有人遇到过同样的问题吗?我有什么想法可以尝试解决这个问题吗?谢谢

  7. ruby - File.realpath() 是否泄漏内存? - 2

    我在使用File.realpath()时遇到问题,留下的字符串似乎没有被垃圾收集。在我看来,这像是内存泄漏,但我无法想象这样的事情对于核心库方法来说真的是真的。考虑以下代码:defstring_test(string)putsstringendGC.startreport=MemoryProfiler.reportdos='./foo.txt'.freezestring_test(s)s=nilGC.startendreport.pretty_print这会产生(以及其他冗长的输出):Totalallocated:0bytes(0objects)Totalretained:0bytes

  8. ruby-on-rails - 用于 Ruby 的 vim 中的全局 "Go to definition"? - 2

    自97年以来我一直在使用vi/vim进行各种快速编辑和管理任务,但最近才考虑使用它来替换Netbeans作为我选择的ruby​​编辑器。我发现一件事在Netbeans和Eclipse中非常有用的是Ctrl+Click“转到定义”功能,您可以在其中按住Ctrl键并单击一个类或方法,然后它将带您了解定义。现在,我玩过丰富的ctags和rails.vim,而且很接近,但没有雪茄。这就是我想要的:默认情况下在Netbeans和Eclipse中,您可以在本地rails中按住ctrl并单击本地方法或类项目,但你也可以ctrl+click定义在gems或用Ruby编写的系统库。以Netbeans为例

  9. ruby - 从 Rails 3.0 升级到 Rails 3.2(Ruby 1.9.3 + Passenger)后出现巨大的内存泄漏/膨胀 - 2

    上周我们将一个在Rails3.0.1上运行的小项目升级到了Rails3.2.2。升级后不久,我们发现偶尔,一天2-3次,我们会看到一个巨大的PhusionPassenger进程(1-5GB)。我们正在运行PhusionPassenger3.0.11和Ruby1.9.3-p0。我们已经尝试了不同的Ruby版本(1.9.2-p290和1.9.3-p125)但没有成功。之后,我们尝试使用Oink来跟踪我们的内存使用情况.不幸的是,Oink没有显示内存膨胀的原因——大型进程似乎不再写入日志文件。当我们降级回Rails3.0.1时,问题就消失了。有没有人有类似的问题?我们确实检查了我们的代码是否

  10. ruby : how to prevent modification of an array instance variable through an attribute reader - 2

    抱歉这个菜鸟问题...假设我们有:classTestMeattr_reader:arraydefinitialize@array=(1..10).to_aend结束然后可以这样做:>>a=TestMe.new=>#>>a.array.map!&:to_s=>["1","2","3","4","5","6","7","8","9","10"]>>a.array=>["1","2","3","4","5","6","7","8","9","10"]这显然不利于封装,不是吗?有什么方法可以快速保护数组变量不被更改吗?...或者每当我的实例变量具有“破坏性”方法时,我是否需要实现一个深拷贝读取

随机推荐