Memory Management

| Comments

昨天在nari桑的minigc时看到sbrk函数,参考man手册后发现基本看不懂。啥program break,data segment都不明白,所以花了点时间多研究下内存布局和管理。

看了一会,其实也没看懂啥,多少记一下几个概念,也不一定对的赶脚。

Virtual Memory

Virtual Memory通过Page Tables把进程所用的虚拟地址(Virtual Addresses)映射到物理地址(Physical Addresses)上。OS会管理虚拟地址空间(Address Space),负责分配真实的内存到虚拟内存。(感觉和LVM是一个道理)

Page Tables

Page Tables是功能就是把虚拟地址映射到物理地址,虚拟地址在访问进程中是唯一的,物理地址在硬件中是唯一的。

Address Space

每个进程会有一块连续的虚拟机地址空间,它由多个内存段(Memory Segments)组成。

Memory Segments

内存段一般有以下几种:

  • Text/Code Segment:包含了可执行的指令,只读,可以被同一进程的不同实例共享。
  • Data Segment (Data + BSS + Heap):数据段由Data,BSS和Heap组成。
    • Data:包含了已经初始化的全局变量和静态变量,可读写,不能共享。
    • BSS:包含了未初始化或者被初始化为0的全局变量和静态变量。
    • Heap:包含了使用malloc,relloc,free管理的内存。malloc,relloc,free可能使用brk和sbrk这些系统调用来调整Heap的大小,也可能使用mmap来获取虚拟内存中保留的非连续区域,heap被所有共享库和动态加载的模块所共享。
  • Stack:进程当前的函数调用堆栈,返回地址,局部变量等。
  • Vdso:由内核自动创建,用来让程序和内核通讯。

上两张图更直观:

Flexible Process Address Space Layout In Linux

Address Space

先写到这里。。。

参考:

Anatomy of a Program in Memory

Measuring memory consumption

Flush DNS Cache in Mac OS

| Comments

在 Mac OS X 10.5 和 10.6中,

1
sudo dscacheutil -flushcache

在 10.7 和 10.8中

1
sudo killall -HUP mDNSResponder

Active Support中的callback

| Comments

在rails中提供了很多callback,model里有before_save, after_save等,controller里有before_filter, after_filter等,他们都是基于activesupport的callback来实现的,callback主要功能实现的代码也在activesupport中,其他只是一层封装,所以研究了下activesupport中callback的实现,记录一下。

从一个简单的用例开始吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# coding: utf-8

require 'active_support/callbacks'

class Record
  include ActiveSupport::Callbacks
  define_callbacks :save

  def save
    run_callbacks :save do
      puts "- save"
    end
  end

  set_callback :save, :before, :saving_message
  def saving_message
    puts "saving..."
    return false
  end

  set_callback :save, :after do |object|
    puts "saved"
  end

end

person = Record.new
person.save

# ---output---
# saving...
# - save
# saved

Rspec 笔记

| Comments

Core

测试单元

describe用来定义一个example group,即一个测试单元。 describecontext用来定一个nested group,即一个子测试单元。 itspecify用来定一个example,即一个测试。

1
2
3
4
5
6
7
8
9
10
describe "something" do
  context "in one context" do
    it "does one thing" do
    end
  end
  describe "in another context" do
    specify "does another thing" do
    end
  end
end

Mac在终端切换网络设置

| Comments

公司的网络是要设置静态ip的,而家里的是自动分配的。每天都要进入Network Preference去切换,烦。

查了下可以通过networksetup -switchtolocation [location name]来切换

networksetup还有很多功能,这只是其中一项,自己查help吧。

NTFS Read/write in Mac OS X Lion

| Comments

以前用破解的Paragon NTFS,自从决定不用任何盗版软件后,就把所有的破解软件全都删了,大部分都找到了免费或者开源的版本,读写NTFS一直都没找到合适的。SL-NTFS我Mac上不起作用。多番搜索后,找到了更简单的办法,只不过比较适合技术人员。

PS: 写本文之前,我以为NTFS-3G也要收费,结果自己搞错了,看成了tuxera-ntfs,用homebrew的同学,直接brew install ntfs-3g吧。

再PS: 我感觉我写的比较好用

参考Mac OS Lion读写NTFS文件系统一文,他提供的方法确实可行,方便起见,写了个脚本处理。

Javascript 系列笔记

| Comments

这是我在学习javascript中整理的笔记,参考了很多其他网站的文章和资料,特此感谢。

理解javascript系列

simple javascript inheritance

understanding javascript oop

使用面向对象的技术创建高级 Web 应用程序

1. 数据类型及内存分配:

  • 基本数据类型,Undefined,Null,Number,String,Boolean,存放在栈中。
  • 符合数据类型,Object,Function,Array,自定义对象,存放在堆中,栈中存放的是指针,指向堆中的对象。

例:

1
2
var name = "kenshin";
var user = new User();

“kenshin”直接存在栈中,name指向它。user存在栈中,它指向堆中的new User()。

基本数据类型和其包装类型

来看看String,Number,Boolean这3个数据类型。

1
2
3
4
5
6
7
var primitive = 1;
var box = new Number(1);
primitive instanceof Number // => false
primitive instanceof Object // => false
box instanceof Number // => true
typeof primitive // => "number"
typeof box // => "object"

直接用字面量定义值,返回的结果直接是基本类型,不是自己的包装类型的实例,也不是Object类型。

不通过new关键字,直接像调用方法一样调用Number,String,Boolean,功能是将包装类型转换为基本类型。

以下都会返回基本数据类型的1

1
2
var num1 = Number(1);
var num2 = Number(new Number(1))

对于基本类型,不要用其包装类型来创建对象,直接用字面量定义,用typeof而不是instanceof来判断是何种类型。

‘安全的’rm脚本

| Comments

周五公司一个同事把他写了N久的代码不小心的rm -rf了,也木有提交,想到我自己也发生过好几次这样的事情,所以还是写了个小脚本来做个预防。直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
safe_rm () {
  for last; do
    echo $last | grep '^-' >/dev/null 2>&1
    if [[ $? == 1 ]]; then
      if [ -e "$last" ]; then
        file=$(echo $last | awk -F/ '{print $NF}')
        mv $last ~/.myTrash/"$file-$(date +%Y-%m-%d-%H-%M-%S)"
      else
        echo "rm: $last: No such file or directory"
      fi
    fi
  done
}

alias rm='safe_rm'

把上面的代码复制到你的shell config文件中,记得手动新建.myTrash文件夹,或者用你喜欢的名字。为了防止重名,最后都带上了时间戳,你可以定时去清理该文件夹。如果你真的很确定你要rm,而不是safe-rm,那你可以在终端用\rm来删除。

迁移到Octopress

| Comments

以前的博客是刚刚学rails时拿来练手写的,一直没有更新。使用过程中一直觉得有些不好用的地方,比如:

  • WYSIWYG编辑器生成的代码太乱
  • 因为是在线编辑,有时候写到一半,触摸板一滑,浏览器后退,白写,虽然后面加了localStorage来实时保存
  • syntaxhighlight的代码高亮实在是不好看

之前就在一些活动中听过Octopress,基于jekyll的静态博客。使用markdown来写博文,远离WYSIWYG的丑陋代码,Octopress还带了一堆OOTB的插件,solarized的代码高亮,Gist,移动平台的兼容布局,社交分享等功能。所以最后决定搬到Octopress上来。搬迁比较麻烦就是以前的文章转过来的难度比较大,要去掉WYSIWYG加上的标签,还有原来的代码高亮的转换等一些问题。考虑下来还是决定不迁移旧博文,在自己的VPS上配置了反向代理,所以依然可以通过以前的链接访问博文,现在的导航栏上也加了legacy,可以回到旧博客中。

最后顺便测试下代码高亮:

octopress.rb
1
2
3
4
5
class Octopress
  def say
    puts "Hello Octopress"
  end
end