Published on
2010年04月15日 in
笔记.
Tags: PL.
好像刚弄明白动态作用域是怎么回事,拿个例子:
var a=0; //global
def f1():
a=1
def f2():
var a; //local
f1()
f2()
puts a
若是静态作用域,f2调用f1,f1修改全局变量a的值为1,输出1。这个多自然…
可是动态作用域就…输出0,全局变量a的值没有变化。
f2不是调用了f1么,f1不是改变a的值么…是啊,f2调用的那个f1改变的是f2那个局部变量a的值。也就是说,同一个函数在不同的环境下调用会有不同的行为。
好吧我正在纳闷为什么会有这种东西存在过…囧
Published on
2010年04月11日 in
笔记.
Tags: GC, VM.
GC多好多好就不多说了。没银弹嘛,什么好处什么坏处都了解下就好 TvT
引用计数
“穷人的垃圾收集”。实现简单,可以在对象失去引用时立即收集,不过对付不了循环引用。“立即收集”容易给人一种“高效”的印象,其实正相反,引用计数中的每个mov指令后面都必须跟着几条额外指令,引用的局部性还不好。跟各种GC算法比起来,引用计数的效率是最低的 :(
CPython是引用计数加备用的mark-sweep,(好像如果一开始就使用GC的话就没必要引入那套复杂的内存池机制了?
mark-sweep
从根(寄存器、局部变量和全局变量等)开始,遍历所有可访问的对象并标记之;再遍历所有变量,将所有没mark的对象收集。
C\C++中的GC实现大约是扫描bss段和堆栈什么的,找到全局变量和局部变量。C\C++中你不知道一块数据是指针还是一个纯洁的整数,所以只能用个is point to heap来猜它是不是指针,如果这个整数恰好是一块内存的地址,就只能“保守地”当它是指针mark掉了。保守式的GC中比较有名的就是Boehm的GC(貌似很靠谱!)。
停止-复制
这个需要额外一倍的内存空间。先将一切活动停止,遍历堆中所有可以访问的对象并将其拷贝到另个堆中,并将将原先的指针统统指向新的堆中对应的地址,完毕后继续程序的执行。
停止复制的同时也紧缩了内存,因而不存在内存碎片的问题(malloc/free在整理堆中碎片时候的各种搬运不容小觑),性能上好像要优于mark-sweep。缺点就是对空间浪费比较大(一倍啊一倍~)。
分代收集
遍历所有对象时候的停滞会比较厉害。想办法把停滞缩短到人类察觉不到吧…就有了分代收集和增量收集 TvT
分代收集基于这样的假设:
1.对象越新,生存期越短;
2.对象越老,生存期越长;
3.少有指向新对象的老对象
就把堆分成n块,对应n代的对象(三代就差不多吧)。再加个记忆表什么的记下指向新对象的老对象,以记忆表中的老对象以及活跃的变量等做根,重点照顾最新的这代就行了。
.net那CLR好像是分代的…缺点是经过多次收集,较老的代会积攒比较多的垃圾。
增量收集
增量收集好像是记住上次遍历到了什么地方,然后每次遍历一点,最后集中收集。
有个三色标记:
白色:未被访问的对象;
灰色:已经被访问过,子对象还未访问;
黑色:已经被访问过,子对象也已被访问;
然后就是性质:
当没有灰色对象时,所有的白色对象都是垃圾;
不会有黑色对象指向白色对象;
每个灰色对象都位于收集器的队列中(作为下次收集的根);
Published on
2010年04月10日 in
杂碎.
好久没更新了…做什么去了呢?
一个解释是越来越好吃懒做了(生活费都拿来吃饭了囧)…再就是挖坑太多了填不过来。总有些东西想要表达却表达不清楚,就产生了这篇不明不白的post TvT
以及各种烂尾:http://github.com/fleurer
Published on
2010年04月2日 in
备忘.
自己写小东西什么的还是git最省心 ^_^
版本控制工具里的命令什么还真够多的,所幸一个人要求不高,平时用的功能也就这么几个了。所以…..忘掉svn吧! =V=
开始
git init
git add .
git commit -a -m "commit message"
git init就是创建当前目录的版本库,所有信息都在.git这一个文件夹里面。比起svn的每个目录下边都一个.svn可要清爽多了 :)
git add . 将目录中的所有文件加入跟踪,新建文件时候别忘了这个。
git commit 就是提交啦~注意下这个commit只是提交到本地。
git是跟踪代码变动的工具,而不是上传工具。commit时候需要注意的一点就是不要把二进制什么的文件交进去。记得在根目录下边加个.gitignore文件,内容大约可以这样:
代码杯具了怎么办~
这样就把blah.c恢复到了commit时的状态,存档复活~
要恢复到之前的版本就用git reset了,git在每次提交的时候都有个hash作为标记,知道这个hash就行了(例如git log或者直接翻github的history之类)
git reset --hard 4df38hdf29f
(reset好像有三种?初学者不用刨根究底的 =v=)
分支
git branch blah
git checkout blah
就创建出了一个名为blah的分支了~
git checkout 的功能就是将当前工作目录转向blah~
合并分支…
git branch master
git merge blah
blah就合并进master啦~
github
ssh密钥好像比较绕…github使用ssh协议传输东东也做了身份验证嘛,所以需要一个双向的密匙。具体的操作步骤忘了囧,不过照着提示来也就一次性的工作啦~
git config --global user.name 'Fleurer'
git config --global user.email me.ssword@gmail.com
git remote add origin git@github.com:(你的名字,这里是Fleurer~)/项目名.git
git push origin master
Comment