今天突然又想起来了lvs,因为不需要硬件,就想自己也安装一个体验一下,由于windows上都不支持,所以就选择了我的Ubuntu;看了一些文档,发现安装太挺麻烦,都需要给内核打补丁,后来在新德里软件包管理器里找了一下,发现里面有了ldirectord,就是我要找的lvs, 还有pptpd,就是我要找了vpn server了,先不管怎么编译了,安装上试试吧。
今天太晚了,以后再研究吧。
关于crontab中启动进程
今天发现一个进程在
futex(0x33a120, FUTEX_WAIT, 2, NULL <unfinished …>
处“阻塞”,反正不往下运行了,就暂且叫“阻塞”吧,而且ps时发现进程状态为“Ss”,看到“s”,我以为是一个deamon,这是一个PHP程序,我 看了看代码,发现里面没有任何关于deamon的处理,也没有while、for等循环语句,怀疑不是一个deamon,但是“s”是怎么出现的呢?
后来发现该进程是从crontab启动的,难道crontab启动的进程都会有“s”,测试了一个程序,确实是这样的。
至于为什么在futex处阻塞,明天再仔细看看源码吧。
关于futex (‘Fast Userspace muTexes’)的相关资料:
http://linux.die.net/man/7/futex
http://javadino.blog.sohu.com/99256728.html
只需更改文件名 iPhone可轻松超频
北京时间5月16日消息,据国外媒体报道,日前有黑客发现了一种给苹果iPhone超频的简单方法,只需更改文件名即可。
据悉,原本iPhone 3G处理器的时钟频率为600MHz,iPhone 3GS为833MHz,但出于多种因素考虑,其分别被苹果限制在了412MHz和600MHz。
而此次黑客发现的这种超频方法,只需重命名一个文件即可。该文件名为“com.apple.SystemPowerProfileDefault.plist”,只需将其更名为“SystemPowerProfileDefaultbak.plist”,然后重启,即可轻松完成超频。
友情提醒:通常,企业限制处理器时钟频率是为了节能、降低热量、延长处理器寿命。如果超频,可能导致设备过热,甚至被损坏,所以小编建议机友们切勿轻易尝试。
rewrite 用法点滴
1. 多个连续的RewriteCond 之间默认是“与”的关系,可以通过 [OR]来说明是“或”的关系, RewriteCond只作用于紧接着的一个RewriteRule
2. RewriteCond的flag有两个可选值: NC: 不区分大小写; OR:表明是“或”的关系
3. RewriteRule的flag常见值有两个:
[P]: 说明立即中断重写处理,然后把处理移交给mod_proxy模块, 如果说立即中断重写处理,则[P,L] 中的L又有什么意义呢?
[L]: 相当于break,不要再继续匹配了,如果这条规则匹配上了,则这就是最后一个匹配了
不常见的几个flag:
[N]: 相当于continue,用当前已经重写好的url再从头开始继续匹配;这样写很难理解,所以很少有这样用的。
[F]: 禁止访问
[R]: 强制重定向,而不是直接代理,对于下面情况R就是多余的,因为没有P标记,则一定是强制重定向:
|
1 2 3 4 5 6 |
^/somepath(.*) http://otherhost/otherpath$1 [R] 对于: ^/somepath(.*) /otherpath$1 [R] 如果没有R,则执行内部重定向,特殊情况下,我们可能通过使用R来强制外部重定向,或者我们 就是希望做一定永久重定向,可以写成如下形式: ^/somepath(.*) /otherpath$1 [R=301] |
程序员与软件工程师
我从来不知道程序员和软件工程师有啥区别,也没有想过程序和软件有啥区别。终于,我越来越发现一个问题,就是,我写程序的水平一定越来越高了,但是我却越来越质疑我的程序的价值了;我可能用了很长时间写出来的程序,根本是没有什么价值的。
一个偶然的机会,我开始思考“程序员”和“软件工程师”这两个概念,我想,它们一定是不一样的,我的理解是:
程序员关心的是程序的正确性和效率,不关心程序的价值,程序员写程序就像某些人打游戏,图的是自己快乐;
软件工程师关心的更重要的是软件的价值,如果该软件不会给他带来渴望的利润,你们即使再好玩,他也不会去做的;既然如此,软件工程师也一定更关心软件的管理了。
我现在非常渴望学习一些软件项目管理的知识,看来我更加关心实际利益了;原来图的是好玩,靠的是兴趣;现在图的是利益,为的是生计。
virtubox 中设置共享目录
VirtualBox可以通过分配数据空间来实现主机和虚拟机之间的数据交换。首先要给虚拟机安装增强功能包,然后在“数据空间”里面添加一个固定分配的数据空间,名称改为share(名称可以任意定)。
如果是Linux系统,以Ubuntu为例,假设挂载目录是/home/testuser/sharefile,直接在终端执行下列命令即可:
sudo mount -t vboxsf share /home/testuser/sharefile/
注意:
1. share为分配数据空间时点名字
2. /home/testuser/sharefile/ 需要是一个存在点空目录
这个时候打开sharefile文件夹,里面就是share中的文件内容了。如果要取消挂载,使用下列命令:
sudo umount /home/buwood-vbox/Desktop/sharefile/
然后在VirtualBox取消分配空间即可。
如果是Windows系统,进入cmd,执行下列指令:
net use z: \\vboxsvr\share
在资源管理器里面就会多出一个网络映射驱动器z,里面是share中的文件内容。如果取消的话,直接在驱动器上点右键,选择“断开”即可,然后在VirtualBox取消分配空间。
Linux 内核源代码下载地址
ftp地址:
ftp://ftp.kernel.org
http地址:
http://www.kernel.org/pub/linux/kernel/
如:
http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.33.4.tar.bz2
Linux操作系统的内存使用方法详细解析
我是一名程序员,那么我在这里以一个程序员的角度来讲解Linux内存的使用。
一提到内存管理,我们头脑中闪出的两个概念,就是虚拟内存,与物理内存。这两个概念主要来自于linux内核的支持。
Linux在内存管理上份为两级,一级是线性区,类似于00c73000-00c88000,对应于虚拟内存,它实际上不占用实际物理内存;一级是具体的物理页面,它对应我们机器上的物理内存。
这里要提到一个很重要的概念,内存的延迟分配。Linux内核在用户申请内存的时 候,只是给它分配了一个线性区(也就是虚存),并没有分配实际物理内存;只有当用户使用这块内存的时候,内核才会分配具体的物理页面给用户,这时候才占用 宝贵的物理内存。内核释放物理页面是通过释放线性区,找到其所对应的物理页面,将其全部释放的过程。
char *p=malloc(2048) //这里只是分配了虚拟内存2048,并不占用实际内存。
strcpy(p,”123”) //分配了物理页面,虽然只是使用了3个字节,但内存还是为它分配了2048字节的物理内存。
free(p) //通过虚拟地址,找到其所对应的物理页面,释放物理页面,释放线性区。
我们知道用户的进程和内核是运行在不同的级别,进程与内核之间的通讯是通过系统调用来完成的。进程在申请和释放内存,主要通过brk,sbrk,mmap,unmmap这几个系统调用,传递的参数主要是对应的虚拟内存。
注意一点,在进程只能访问虚拟内存,它实际上是看不到内核物理内存的使用,这对于进程是完全透明的。
glibc内存管理器
那么我们每次调用malloc来分配一块内存,都进行相应的系统调用呢?
答案是否定的,这里我要引入一个新的概念,glibc的内存管理器。
我们知道malloc和free等函数都是包含在glibc库里面的库函数,我们试想一下,每做一次内存操作,都要调用系统调用的话,那么程序将多么的低效。
实际上glibc采用了一种批发和零售的方式来管理内存。glibc每次通过系统调用的方式申请一大块内存(虚拟内存),当进程申请内存时,glibc就从自己获得的内存中取出一块给进程。
内存管理器面临的困难
我们在写程序的时候,每次申请的内存块大小不规律,而且存在频繁的申请和释放,这样 不可避免的就会产生内存碎块。而内存碎块,直接会导致大块内存申请无法满足,从而更多的占用系统资源;如果进行碎块整理的话,又会增加cpu的负荷,很多 都是互相矛盾的指标,这里我就不细说了。
我们在写程序时,涉及内存时,有两个概念heap和stack。传统的说法stack的内存地址是向下增长的,heap的内存地址是向上增长的。
函数malloc和free,主要是针对heap进行操作,由程序员自主控制内存的访问。
在这里heap的内存地址向上增长,这句话不完全正确。
glibc对于heap内存申请大于128k的内存申请,glibc采用mmap的方式向内核申请内存,这不能保证内存地址向上增长;小于128k的则采用brk,对于它来讲是正确的。128k的阀值,可以通过glibc的库函数进行设置。
这里我先讲大块内存的申请,也即对应于mmap系统调用。
对于大块内存申请,glibc直接使用mmap系统调用为其划分出另一块虚拟地址,供进程单独使用;在该块内存释放时,使用unmmap系统调用将这块内存释放,这个过程中间不会产生内存碎块等问题。
针对小块内存的申请,在程序启动之后,进程会获得一个heap底端的地址,进程每次 进行内存申请时,glibc会将堆顶向上增长来扩展内存空间,也就是我们所说的堆地址向上增长。在对这些小块内存进行操作时,便会产生内存碎块的问题。实 际上brk和sbrk系统调用,就是调整heap顶地址指针。
那么heap堆的内存是什么时候释放呢?
当glibc发现堆顶有连续的128k的空间是空闲的时候,它就会通过brk或sbrk系统调用,来调整heap顶的位置,将占用的内存返回给系统。这时,内核会通过删除相应的线性区,来释放占用的物理内存。
下面我要讲一个内存空洞的问题:
一个场景,堆顶有一块正在使用的内存,而下面有很大的连续内存已经被释放掉了,那么这块内存是否能够被释放?其对应的物理内存是否能够被释放?
很遗憾,不能。
这也就是说,只要堆顶的部分申请内存还在占用,我在下面释放的内存再多,都不会被返回到系统中,仍然占用着物理内存。为什么会这样呢?
这主要是与内核在处理堆的时候,过于简单,它只能通过调整堆顶指针的方式来调整调整程序占用的线性区;而又只能通过调整线性区的方式,来释放内存。所以只要堆顶不减小,占用的内存就不会释放。
提一个问题:
char *p=malloc(2);
free(p)
为什么申请内存的时候,需要两个参数,一个是内存大小,一个是返回的指针;而释放内存的时候,却只要内存的指针呢?
这主要是和glibc的内存管理机制有关。glibc中,为每一块内存维护了一个chunk的结构。glibc在分配内存时,glibc先填写chunk结构中内存块的大小,然后是分配给进程的内存。
chunk ——size
p———— content
在进程释放内存时,只要 指针-4 便可以找到该块内存的大小,从而释放掉。
注:glibc在做内存申请时,最少分配16个字节,以便能够维护chunk结构。
glibc提供的调试工具:
为了方便调试,glibc 为用户提供了 malloc 等等函数的钩子(hook),如 __malloc_hook
对应的是一个函数指针,
void *function (size_t size, const void *caller)
其中 caller 是调用 malloc 返回值的接受者(一个指针的地址)。另外有 __malloc_initialize_hook函数指针,仅仅会调用一次(第一次分配动态内存时)。(malloc.h)
一些使用 malloc 的统计量(SVID 扩展)可以用 struct mallinfo 储存,
可调用获得。
struct mallinfo mallinfo (void)
如何检测 memory leakage?glibc 提供了一个函数
void mtrace (void)及其反作用void muntrace (void)
这时会依赖于一个环境变量 MALLOC_TRACE 所指的文件,把一些信息记录在该文件中
用于侦测 memory leakage,其本质是安装了前面提到的 hook。一般将这些函数用
#ifdef DEBUGGING 包裹以便在非调试态下减少开销。产生的文件据说不建议自己去读,
而使用 mtrace 程序(perl 脚本来进行分析)。下面用一个简单的例子说明这个过程,这是
源程序:
#include
#include
#include
intmain( int argc, char *argv[] )
{
int *p, *q ;
#ifdef DEBUGGING
mtrace( ) ;
#endif
p = malloc( sizeof( int ) ) ;
q = malloc( sizeof( int ) ) ;
printf( "p = %p\nq = %p\n", p, q ) ;
*p = 1 ;
*q = 2 ;
free( p ) ;
return 0 ;
}
很简单的程序,其中 q 没有被释放。我们设置了环境变量后并且 touch 出该文件
执行结果如下:
p = 0x98c0378q = 0x98c0388
该文件内容如下
= Star
t@./test30:[0x8048446] + 0x98c0378 0x4
@ ./test30:[0x8048455] + 0x98c0388 0x4
@ ./test30:[0x804848f] – 0x98c0378
到这里我基本上讲完了,我们写程序时,数据部分内存使用的问题。
代码占用的内存
数据部分占用内存,那么我们写的程序是不是也占用内存呢?
在linux中,程序的加载,涉及到两个工具,linker 和loader。Linker主要涉及动态链接库的使用,loader主要涉及软件的加载。
1、 exec执行一个程序
2、 elf为现在非常流行的可执行文件的格式,它为程序运行划分了两个段,一个段是可以执行的代码段,它是只读,可执行;另一个段是数据段,它是可读写,不能执行。
3、 loader会启动,通过mmap系统调用,将代码端和数据段映射到内存中,其实也就是为其分配了虚拟内存,注意这时候,还不占用物理内存;只有程序执行到了相应的地方,内核才会为其分配物理内存。
4、 loader会去查找该程序依赖的链接库,首先看该链接库是否被映射进内存中,如果没有使用mmap,将代码段与数据段映射到内存中,否则只是将其加入进程的地址空间。这样比如glibc等库的内存地址空间是完全一样。
因此一个2M的程序,执行时,并不意味着为其分配了2M的物理内存,这与其运行了的代码量,与其所依赖的动态链接库有关。
运行过程中链接动态链接库与编译过程中链接动态库的区别。
我们调用动态链接库有两种方法:一种是编译的时候,指明所依赖的动态链接库,这样loader可以在程序启动的时候,来所有的动态链接映射到内存中;一种是在运行过程中,通过dlopen和dlfree的方式加载动态链接库,动态将动态链接库加载到内存中。
这两种方式,从编程角度来讲,第一种是最方便的,效率上影响也不大,在内存使用上有些差别。
第一种方式,一个库的代码,只要运行过一次,便会占用物理内存,之后即使再也不使用,也会占用物理内存,直到进程的终止。
第二中方式,库代码占用的内存,可以通过dlfree的方式,释放掉,返回给物理内存。
这个差别主要对于那些寿命很长,但又会偶尔调用各种库的进程有关。如果是这类进程,建议采用第二种方式调用动态链接库。
占用内存的测量
测量一个进程占用了多少内存,linux为我们提供了一个很方便的方法,/proc目录为我们提供了所有的信息,实际上top等工具也通过这里来获取相应的信息。
/proc/meminfo 机器的内存使用信息
/proc/pid/maps pid为进程号,显示当前进程所占用的虚拟地址。
/proc/pid/statm 进程所占用的内存
[root@localhost ~]# cat /proc/self/statm
654 57 44 0 0 334 0
输出解释
CPU 以及CPU0。。。的每行的每个参数意思(以第一行为例)为:
参数 解释 /proc//status
Size (pages) 任务虚拟地址空间的大小 VmSize/4
Resident(pages) 应用程序正在使用的物理内存的大小 VmRSS/4
Shared(pages) 共享页数 0
Trs(pages) 程序所拥有的可执行虚拟内存的大小 VmExe/4
Lrs(pages) 被映像到任务的虚拟内存空间的库的大小 VmLib/4
Drs(pages) 程序数据段和用户态的栈的大小 (VmData+ VmStk )4
dt(pages) 04
查看机器可用内存
/proc/28248/>free
total used free shared buffers cached
Mem: 1023788 926400 97388 0 134668 503688
-/+ buffers/cache: 288044 735744
Swap: 1959920 89608 1870312
我们通过free命令查看机器空闲内存时,会发现free的值很小。这主要是因为,在linux中有这么一种思想,内存不用白不用,因此它尽可能的cache和buffer一些数据,以方便下次使用。但实际上这些内存也是可以立刻拿来使用的。
所以 空闲内存=free+buffers+cached=total-used
查看进程使用的内存
查看一个进程使用的内存,是一个很令人困惑的事情。因为我们写的程序,必然要用到动态链接库,将其加入到自己的地址空间中,但是/proc/pid/statm统计出来的数据,会将这些动态链接库所占用的内存也简单的算进来。
这样带来的问题,动态链接库占用的内存有些是其他程序使用时占用的,却算在了你这里。你的程序中包含了子进程,那么有些动态链接库重用的内存会被重复计算。
因此要想准确的评估一个程序所占用的内存是十分困难的,通过写一个module的方式,来准确计算某一段虚拟地址所占用的内存,可能对我们有用。(T002)
转自: http://linux.ccidnet.com/art/302/20070524/1089197_1.html
windows 调试工具
微软官方的东西windbg:
http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx
一个windows上的wiki引擎
WikiPlex is a regular expression based wiki engine that allows developers to integrate a wiki experience into an existing .NET application seamlessly and with little effort. Built and used by the CodePlex team, WikiPlex has been thoroughly tested in real-world scenarios!
http://wikiplex.codeplex.com/
关于codeplex:
http://codeplex.codeplex.com/wikipage?title=About%20the%20CodePlex%20Site&referringTitle=CodePlex%20Documentation
好像是一个用于团队开发项目的程序