从哪里看起呢?
首先应该看看空间在哪里分配,内存占用是如何吧
那哪些语句可能导致内存的分配呢?
Class.new
这肯定是一个来源,不过似乎new不是一个关键词。从试验中可以看出new和类的其他方法一样,并没有独立出来。特殊的是new应该是解释器在读入class定义时自动加入的。那么首要任务是找到new方法加入的代码。
一番搜索,没有发现Class.new的有关代码,倒是不经意发现了gc.c中的rb_newobj(NEWOBJ)函数(真是傻,这个明显嘛),看看发现时候返回的是一个RVALUE的指针,RVALUE基本可以看成一个union,它可以存储的内容包括
看到这里,觉得有点汗,不会ruby里的所有数据都按这个组合成树的结构吧,那样的话,效率实在。。。。
再看!
再看看string的表达
首先,RString定义为
struct RString {
struct RBasic basic;
long len;
char *ptr;
union {
long capa;
VALUE shared;
} aux;
};
在string.c中有rb_str_new(简单调用后者)和str_new来完成string的分配
str_new的部分代码
str = str_alloc(klass); 调用NEWOBJ来获得空间
RSTRING(str)->len = len; 设置几个RString的域
RSTRING(str)->aux.capa = len;
RSTRING(str)->ptr = ALLOC_N(char,len+1); 调用xmalloc来获取空间
if (ptr) {
memcpy(RSTRING(str)->ptr, ptr, len);
}
RSTRING(str)->ptr[len] = '/0'; 还是得加上0
return str;
一个与gc有关的类型是RVarmap
struct RVarmap {
struct RBasic super;
ID id;
VALUE val;
struct RVarmap *next;
};
在rb_eval对应于NODE_DASGN中找到的代码指向了dvar_asgn_internal函数,其中的变量用ruby_dyna_vars为头的链表组织起来,赋值的操作分为两个部分,第一部分找到对应的变量,若有则直接赋值然后返回。第二部分要新建一个RVarmap的节点,做相应的赋值操作
用链表组织变量和进行查找有些不可思议,怀疑DASGN对应的操作是 局部变量的赋值(这个也明显不是,但到底是什么呢?)
首先应该看看空间在哪里分配,内存占用是如何吧
那哪些语句可能导致内存的分配呢?
Class.new
这肯定是一个来源,不过似乎new不是一个关键词。从试验中可以看出new和类的其他方法一样,并没有独立出来。特殊的是new应该是解释器在读入class定义时自动加入的。那么首要任务是找到new方法加入的代码。
一番搜索,没有发现Class.new的有关代码,倒是不经意发现了gc.c中的rb_newobj(NEWOBJ)函数(真是傻,这个明显嘛),看看发现时候返回的是一个RVALUE的指针,RVALUE基本可以看成一个union,它可以存储的内容包括
union
{
struct { 这个是当该RVALUE未被使用时用做链表的内容
unsigned long flags; /* always 0 for freed obj */
struct RVALUE *next;
} free;
struct RBasic basic;
struct RObject object;
struct RClass klass;
struct RFloat flonum;
struct RString string;
struct RArray array;
struct RRegexp regexp;
struct RHash hash;
struct RData data;
struct RStruct rstruct;
struct RBignum bignum;
struct RFile file;
struct RNode node;
struct RMatch match;
struct RVarmap varmap;
struct SCOPE scope;
} as ;
struct { 这个是当该RVALUE未被使用时用做链表的内容
unsigned long flags; /* always 0 for freed obj */
struct RVALUE *next;
} free;
struct RBasic basic;
struct RObject object;
struct RClass klass;
struct RFloat flonum;
struct RString string;
struct RArray array;
struct RRegexp regexp;
struct RHash hash;
struct RData data;
struct RStruct rstruct;
struct RBignum bignum;
struct RFile file;
struct RNode node;
struct RMatch match;
struct RVarmap varmap;
struct SCOPE scope;
} as ;
再看!
再看看string的表达
首先,RString定义为
struct RString {
struct RBasic basic;
long len;
char *ptr;
union {
long capa;
VALUE shared;
} aux;
};
在string.c中有rb_str_new(简单调用后者)和str_new来完成string的分配
str_new的部分代码
str = str_alloc(klass); 调用NEWOBJ来获得空间
RSTRING(str)->len = len; 设置几个RString的域
RSTRING(str)->aux.capa = len;
RSTRING(str)->ptr = ALLOC_N(char,len+1); 调用xmalloc来获取空间
if (ptr) {
memcpy(RSTRING(str)->ptr, ptr, len);
}
RSTRING(str)->ptr[len] = '/0'; 还是得加上0
return str;
一个与gc有关的类型是RVarmap
struct RVarmap {
struct RBasic super;
ID id;
VALUE val;
struct RVarmap *next;
};
在rb_eval对应于NODE_DASGN中找到的代码指向了dvar_asgn_internal函数,其中的变量用ruby_dyna_vars为头的链表组织起来,赋值的操作分为两个部分,第一部分找到对应的变量,若有则直接赋值然后返回。第二部分要新建一个RVarmap的节点,做相应的赋值操作
用链表组织变量和进行查找有些不可思议,怀疑DASGN对应的操作是 局部变量的赋值(这个也明显不是,但到底是什么呢?)