ruby gtk-3上的内存泄漏

ruby gtk-3上的内存泄漏,ruby,memory-leaks,gtk3,Ruby,Memory Leaks,Gtk3,我在使用gtk-3的ruby 2.3.1上遇到内存泄漏。 在我的系统(Ubuntu 16-04)上,下面的代码消耗大约80MB。 picture.jpg的大小为289kb `需要“gtk3” def ptest i=0 j=0 loop { i += 1 j += 1 exit if j==50 @image = Gtk::Image.new newPixbuf = GdkPixbuf::Pixbuf.new(:file =&g

我在使用gtk-3的ruby 2.3.1上遇到内存泄漏。 在我的系统(Ubuntu 16-04)上,下面的代码消耗大约80MB。 picture.jpg的大小为289kb

`需要“gtk3”

  def ptest
    i=0
    j=0
    loop {
    i += 1
    j += 1
    exit if j==50
    @image = Gtk::Image.new
    newPixbuf = GdkPixbuf::Pixbuf.new(:file => "picture.jpg")
    @image.pixbuf = newPixbuf
    @image.clear
    @image=nil
    if i == 10
      p "GC"
      GC.start
      i = 0
    end
    }
  end

  ptest`

根据法律,这不应该发生。如何释放内存?

我不喜欢Ruby,但了解一些Gtk+。 在C语言中,您必须自己处理内存分配,您需要取消pixbuf

发件人:

GtkImage不假定引用pixbuf;如果你有自己的参考资料,你仍然需要撤销它

因此,最有可能的情况是,如果Ruby没有实现ARC(基于Gobject的自动引用计数),您必须在
@image.pixbuf=newPixbuf
之后立即执行类似于
newPixbuf.unref
(不确定Ruby语法)的操作


希望有帮助。

首先我不认识Ruby

虽然您的“picture.jpg”文件的大小为289KB,但它将使用比未压缩时更多的内存空间

您正在创建一个Gtk::Image并将您的映像添加到其中。GTK+将创建此OK,但当您销毁它时,GTK+分配给它的内存不会立即释放

来自GTK+C文档

需要注意的是,gtk_widget_destroy()只会导致 如果没有额外的参考,则使用 g_object_ref(),在其上保持不变。如果有其他参考资料 调用此命令后,小部件将处于“惰性”状态 功能小部件仍将指向有效内存,允许您 释放您持有的引用,但您不能查询小部件的 自己的国家


当控制返回GTK+“主回路”时,应释放内存。在您的示例中没有完成,也没有初始化或启动。

显然,我的Ruby gdk3 Gem中有一个bug。gem更新解决了这个问题。

这也是我的第一个想法,但不幸的是ruby中没有针对Pixbuf对象的unref方法。所以我认为ruby垃圾收集器GC应该完成这项工作,但它没有。unref方法不是一个Pixbuf方法,而是一个GObject方法,Pixbuf继承自GObject。刚刚看到GC是一个垃圾收集器,但也许gobject内省在Ruby中不是那么稳定。我试着阅读一下Ruby Gtk+,事实上Glibc的ref/unref/reference计数方法存在一些问题。你能尝试一个与你提供的链接上的方法几乎相似但稍加调整的解决方案吗?:
静态值unref(self)值self;{g_object_unref(_SELF(SELF));返回Qnil;}。。。并修改了幻灯片放映代码。。。newPixbuf=Gdk::Pixbuf.new(@filenames.next,1024800)@image.Pixbuf=newPixbuf newPixbuf.unref
不幸的是,我不知道如何将“unref”方法添加到Gdk::Pixbuf。这当然不可能从Ruby内部实现,我更喜欢Ruby。GC应该处理好这件事,但可能需要启动。一个解决方案可能是尝试创建一个方法,其中pixbuf具有本地作用域,这可能会迫使GC处理它,比如说,一个名为get_image_from_file的方法,该方法反过来返回一个Gtk::image并将文件名作为参数。pixbuf将仅在该方法中本地使用,这可能会欺骗GC,因为我们还有垃圾要收集/当然,我在主循环中测试了代码,但没有结果。我同意应该释放Pixbuf对象的引用,但我不知道如何释放。