gpt4 book ai didi

c++ - 嵌入式 Ruby GC 和包装结构

转载 作者:太空宇宙 更新时间:2023-11-04 14:14:28 25 4
gpt4 key购买 nike

我有一个嵌入了 ruby​​ 1.9.3 的 win32 控制台应用程序,我遇到了 ruby​​ GC 和包含指向大数据指针的包装 C 结构的对象的问题。

经过一些测试,ruby 似乎在孤立对象占用一些内存时运行 GC。问题是 ruby​​ 没有考虑结构指针占用的内存大小,所以它不会启动 GC,因为它认为那些孤立的对象太小并且不会占用太多内存。

我制作了一个示例应用程序,它会在其包装结构中创建大量包含大数据的对象时崩溃,这是代码:

#include <ruby.h>

typedef struct TestClassStructS {
byte* bytes;
} TestClassStruct;

static void testClassFree(TestClassStruct *p) {
delete p->bytes;
delete p;
}

VALUE testClassNew(VALUE klass) {
TestClassStruct* ptr = new TestClassStruct();
ptr->bytes = new byte[1024 * 1024 * 5]();
VALUE obj = Data_Wrap_Struct(klass, NULL, testClassFree, ptr);
rb_obj_call_init(obj, 0, 0);
return obj;
}

VALUE testClassInitialize(VALUE self) {
return self;
}

typedef VALUE (*rubyfunc)(...);

VALUE require_wrap(VALUE arg)
{
return rb_eval_string("GC.enable; loop do; TestClass.new; end");
}

int main(int argc, char** argv[])
{
RUBY_INIT_STACK;
ruby_init();
//freopen("CON", "w", stdout);
ruby_init_loadpath();
ruby_sysinit(&argc, argv);

VALUE testClass = rb_define_class("TestClass", rb_cObject);
rb_define_singleton_method(testClass, "new", (rubyfunc)testClassNew, 0);
rb_define_method(testClass, "initialize", (rubyfunc)testClassInitialize, 0);

int error;
VALUE result = rb_protect(require_wrap, 0, &error);
if (error)
{
VALUE lasterr = rb_gv_get("$!");
VALUE message = rb_obj_as_string(lasterr);

printf(StringValuePtr(message));
}

return ruby_cleanup(0);
}

这不是真实案例,但让我担心在某些情况下,如果 GC 未启动,我的应用可能会占用太多内存。

我可以通过定期调用 GC.start 来解决这个问题,但对我来说这似乎是一个肮脏的解决方案。

如果有一种方法可以让 ruby​​ 在某些对象被孤立时优先进行垃圾回收,或者告诉 ruby​​ c 结构在内存中占用的实际大小,那将是一个不错的解决方案,但我不知道 ruby​​ api 是否包含某些东西像这样,我找不到类似的东西。

最佳答案

如果可以,请使用 xmalloc(我认为来自 ruby​​.h)分配内存。也就是说,到目前为止,这是确保分配的内存用于下一个 GC 触发器的唯一方法。

有一个用包装的 C 结构注册的新 dsize 函数,但它似乎没有(还?)在 ruby​​ 1.9.3 中使用

关于c++ - 嵌入式 Ruby GC 和包装结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12452069/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com