作者:zuoxiaolong8810(左潇龙),转载请注明出处。
魔都国贸附近,某天夜里十一点半。
那一晚,魔都出奇的没有做只打雷不下雨的勾当,老天似乎是要将魔都淹没一般,倾盆大雨像不要命似的拍打着地面。
漆黑的夜幕中,一道黑影从一个十字路口狂奔而出,而就在此时,一辆红色宝马急速穿过,一瞬间,黑影就犹如被巨力抛飞一般腾空而起,直到几秒钟后,才重重的摔落在车前十多米处。
“吱...兹....”
一声凄厉的刹车声划破了魔都的长空。
之后,一个身材高挑的女子,慌忙的从车中奔跑到黑影落下的地方,或许是由于看到倒下之人满身鲜血的模样,女子吓的不禁发出一声惊叫后退了几步,愣是咬着牙迟迟不敢上前。
或许是由于慌乱之下失了神,女子后退的时候,差点被一个物体绊倒。女子低头一看,竟然是一只拖鞋,不知为何,看到这一幕,一时间女子的心绪稳定了不少。
待得情绪稳定以后,女子这才再次意识到自己撞到人了,而此人到现在还不知死活。于是女子急忙再次跑到黑影身旁,开始试图叫醒这位被自己撞伤的路人,而由于此时一直是大雨倾盆,被撞之人身上的鲜血已经被冲刷干净,女子也渐渐的看清了黑影的面貌。
此人看起来年纪不大,穿着一条大裤衩和一条普通的黑色T恤,光着两个脚丫子,五官倒还算端正,只是满脸的青春痘将其仅有的一点英俊全部淹没,不过从此人光着的脚丫子就可以看出,刚才地上的拖鞋应该就是此人被撞飞的鞋子了。
久久尝试叫醒伤者未果之后,女子无奈之下,只好使出浑身的力气才堪堪拖动此人,等到将受伤之人拖入车中之后,女子其实已经累的满身大汗,只是在这风雨交加的夜晚,看不出来罢了。
XX医院急救室。
“你说什么?死了?”女子瞪大着一双晶莹的眼珠,不可思议的凝视着眼前宣布结果的医生。
此时,在灯光的照耀下,才看清女子的面貌,女子穿着一身白色蕾丝连衣裙,一双眼睛简直像浸在水中的水晶一样澄澈,肤色晶莹如玉,薄薄的唇,色淡如水,清秀的五官里透露出一种说不出的乖巧。而且由于刚才被大雨淋湿,女子的全身已经湿透,仔细看去,隐约可见其包裹在着装之内的嫩肤,更是给原本就美到极点的女子添加了一份诱人的姿色。
“是的,本来接上输氧管后是有微弱的呼吸的,结果过了几秒钟之后就彻底断气了,对不起,我们已经尽力了。”医生叹息一声说道,紧接着,医生继续说道:“这是他临死前让我给你的,请节哀吧”。说着,医生便将手中的一张纸条递给了女子,而快接触到女子玉手的时候,医生忍不住吞了口口水,显然是被女子的美色惊到了。
女子在听完医生的宣判之后,差点晕倒在地,幸好离座位很近,所以才一屁股做到了座位上,不至于摔倒。呆呆的望着正在被缓缓的推往太平间的急救车,女子有点不知所措,她到现在甚至都不知道自己撞死之人姓谁名谁。
想起刚才医生说的话,女子这才意识到手中握着的纸条,打开一看,女子的表情瞬间凝固了,只见纸条上歪歪曲曲的写着几个字:你TM踩着我输氧管了。
XX医院太平间。
“尼玛,二货医生,老子用尽了生前的力量,才勉强写了那么几个字。这蠢货也不打开看看,竟然以为我是临死前写给女友的小情书,也不想想,老子命都快没了, 还写毛毛情书啊。再说,看我这屌丝样,外面那女神能是我女友吗。我真是去年买了个表。” 骂骂咧咧的声音从太平间中传来,这要是被他人听到了,估计当场就要被吓昏过去。
只见一个人影从急救床上缓缓的坐起来,令人惊奇的是,此人竟然生生的穿过了铺在身上的白布,看上去就像是此人不存在一般。坐起的一人,正是被刚才的貌美女子撞死之人,而此人,正是加班到深夜的小左。
“貌似老子转生了啊,就是这身体咋跟个魂儿似的,完全没有实体感啊。难道让我就这样每天飘来飘去的,我擦。”看着自己几乎透明的身体,小左没有时间为自己的死后转生所兴奋,而是紧皱着眉头开始琢磨自己的身体。
“啊哈,我拥有异能了啊,这简直是太TM逆天了。”小左研究了将近三个小时,终于发现了自己的异常。然而在发现自己竟然神奇的拥有了异能之后,小左已然压抑不住内心的兴奋,在太平间里大喊大叫,完全不顾身边沉睡的众人们。
不过兴奋只持续了片刻,小左便眉头紧皱,一脸闷闷不乐的样子,因为他的面前站着八个小左,是的,八个。
小左在研究以后发现,他是拥有异能没错,而且可以转换成屌丝和高富帅的形象,但是让人抓狂的是,他必须先分离出屌丝和高富帅的分身,然后才能由这两个分身,再次分离出带有异能的屌丝和高富帅形象的分身,这些异能分别都有隐身,飞行以及读心术,而且一个分身同时只能有一种能力。所以这样两两组合,最后就出现了八个小左,分别是纯屌丝和高富帅分身,以及拥有一种异能的三个屌丝分身,以及分别拥有一种异能的三个高富帅分身。
不过令人欣喜的是,这八个分身都是真真实实的实体,或者说他们除了有特殊能力之外,其实和现实中的人类是一模一样的,尤其是具有屌丝模样的分身,完全和身前的小左一模一样。不过小左变成高富帅以后的样子,倒是真的很帅,长眉若柳,身如玉树,原本坑坑洼洼的脸庞一时间也光滑嫩白,比之女生也丝毫不差。想必就这个样子,除非是与小左特别熟悉的人,才能仔细的从这分身当中看出一丝似曾相识的感觉。
只是目前这种情况虽说有意外的惊喜,但小左仍然觉得十分糟糕。
原因就是,他要是想使用带有异能的分身,则至少需要创造两次分身,一次无技能的屌丝或者高富帅分身,一次则是在此基础上分离出带有异能的分身。还有更致命的一点,就是如果以后正在使用某一个技能的分身,而恰巧在关键时刻需要使用当前异能之外的两个的话,则需要临时替换掉分身,而替换一个分身,则至少需要两次分身的分离。要知道,分身的产生可是相当耗时的,虽说也不长,但十分八分的,还是要的。
“不知道这种情况,能不能用设计模式解决呢?”哪怕是死后转生,思维方式依旧没有变化。前世身为程序猿的小左,在转生后遇到问题时,第一时间想到的,竟然是设计模式。
说干就干,小左收起八个分身,便控制着自己飘忽的身体开始寻找电脑,因为必须要有电脑,才能激发自己的设计灵感。
寻找的途中,小左也发现,别人竟然完全看不到自己,不过这其实早在小左的意料之中。至于原因,用脚趾头都能想的明白,都已经变成魂魄了,还能看见个毛啊。
由于此时已至深夜,所以医院所剩的工作人员寥寥无几,凭借着可以穿透一切实物的身体,小左很轻易的就找到了一个无人的办公室。不过当小左按下电脑开机键的时候,竟然发现自己的手直接穿过了机箱。
“靠!”愤怒的爆了声粗口,无奈
Android Tools中的DDMS带有一个很不错的跟踪内存分配的工具Allocation tracker。通过Alloction tracker,不仅知道分配了哪类对象,还可以知道在哪个线程、哪个类、哪个文件的哪一行。
尽管在性能关键的代码路径上移除所有的内存分配操作不是必须的,甚至有时候是不可能的,但是Alloction tracker可以帮你识别代码中的一些重要问题。
举例来说,许多应用中发现的一个普遍错误:每次进行绘制都创建一个新的Paint对象。将Paint的创建移到一个实例区域里,是一个能极大提高程序性能的简单举措。
在Eclipse中安装和使用Allocation tracker步骤
Eclipse安装Allocation tracker插件
Andorid开发环境的时候,默认将该工具包含到ADT插件中。所以不必有额外的安装。
启动Eclipse,切换到DDMS透视图(步骤同Heap)
将手机连接通过USB链接到电脑(步骤同Heap)
选中想要检检测的进程(步骤同Heap)
跟踪内存检查的信息
单击Allocation tracker标签,就会打开一个新的窗口,点击“Start Tracing“按钮,然后让引用运行你想分析的代码。运行完毕后,点击”Get Allocations“按钮。
一个个一分配对象的列表就会出现在第一个表格中。单击表格中的任何一项,在表格二中就会出现导致内存分配的栈跟踪信息。
进程的目的就是担当分配资源的实体,一个进程又几个用户线程程。每个线程代表一个执行流。线程的实现方法有三种:1、用户级线程;2、内核级线程;3、混合线程模型。Linux内核中的进程和线程都用相同的数据结构task_struct表示;线程是特殊的进程,共享同一地址空间、共同合作。
进程描述符都是task_struct,包含了与进程相关的所有信息。一般来说能被调度的每个执行上下文都必须拥有自己的task_struct,即使是轻量级线程。
进程状态
可执行状态(TASK_RUNNING):处于这个状态要么在CPU上执行,要么准备执行。
可中断的睡眠状态(TASK_INTERRUPTIBLE):进程被挂起,指导某个条件变为真,产生一个硬件中断,释放进程正在等待的资源或传递一个信号把进进程唤醒,从而使等待的进程回到TASK_RUNNING。
不可中断的睡眠状态(TASK_UNINTERRUPTIBLE):不能通过信号唤醒。
暂停状态(TASK_STOPPED ):进程收到SIGSTOP、SIGTSTP、SIGTTIN或SIGTTOU信号进入暂停状态。
跟踪状态( TASK_TRACED):进程的执行已由debugger程序暂停。
僵死状态(EXIT_ZOMBIE):进程的执行被终止,但是父进程还没有发布wait4()或waitpid()系统调用来返回关于死亡进程的信息。发布wait()系统调用之前,内核不能丢弃包含在死亡进程描述符中的数据,因为父进程还需要它。
僵死撤销状态(EXIT_DEAD):父进程刚发布wait4()或waitpid()系统调用,因而进程被删除。
进程描述符
Unix系统通过pid来标识进程,linux把不同的pid与系统中每个进程或轻量级线程关联,而unix程序员希望同一组线程具有共同的pid,遵照这个标准linux引入线程组的概念。一个线程组所有线程与领头线程具有相同的pid,存入tgid字段,getpid()返回当前进程的tgid值而不是pid的值。
Linux把thread_info(线程描述符)和内核态的线程堆栈存放在一起,这块区域通常是8192K(占两个页框),其实地址必须是8192的整数倍。从图中看出thread_info和task_struct结构互联。
union thread_union {
struct thread_info thread_info;
unsigned long stack[2048];
}
esp是寄存器CPU栈指针。用来存放栈顶单元的地址。栈是从高地址向下生长,用户态刚切换到内核态以后,进程的内核栈总是空的,esp指向顶端。一旦有数据写入,esp就递减。thread_info是52字节大小,所以内核栈最大能扩大8140个字节。
可以很容易从esp寄存器获得当前正在CPU上运行的进程thread_info结构的地址。只要取高13位,低8位置0就行了。其实宏current_thread_info()实现的功能,因为thiread_info->task偏移地址为0,所以该宏等价于current_thread_info()->task。
movl $0xffffe000 %ecx
andl%esp %ecx
movl %ecx,p //地址存在p中
进程运行队列(就绪队列)
Linux内核定义了一个list_head数据结构,字段head和prev分别表示通用的双向链表向前和向后的指针元素。每个task_struct包含一个list_head类型的run_list字段。
在Linux 2.4内核中,就绪进程队列是一个全局数据结构,所有的处理器共享同一个队列。调度器对它的所有操作都会因全局自旋锁而导致系统各个处理机之间的等待,使得就绪队列成为一个明显的瓶颈[2,3]。2.6内核重新设计就绪进程队列为每CPU的数据结构,每个处理器都维护一个自己的就绪队列,这样就避免了2.4内核中的SMP性能瓶颈。
每个CPU的就绪进程队列由一个struct runqueue结构描述,其中最关键的子结构是优先级就绪数组。每个runqueue包含两个优先级就绪数组:active和expired数组。active 指向时间片没用完、当前可被调度的就绪进程,expired 指向时间片已用完的就绪进程。当一个进程的时间片耗尽后,内核在将其放入expired数组前单独计算该进程的时间片。而当active数组为空时(即active数组中所有进程的时间片全部耗尽),通过简单的调换active和expired指针实现所有进程时间片的重算,该过程是O(1)量级的,与系统中的进程数目无关。
描述优先级就绪数组的数据结构是prio_array_t,定义为:
struct prio_array {
int nr_active;//链表中进程描述符的数量
unsigned long bitmap[BITMAP_SIZE]; //优先权位图,优先权队列不为空则置位
struct list_head queue[MAX_PRIO]; //140个优先权队列的头结点
};
Runqueue结构中另两个重要的成员变量是best_expired_prio和expired_timestamp。前者记录expired 就绪进程组中的最高优先级,后者用来表征