| 泠岚's profile雪汐斋PhotosBlogLists | Help |
|
|
June 18 Essential Insights of Living昨天被师兄拜托写作文,果然是很久不练手生了,一个400words的东东折腾了快一个小时,一点多才睡下。写完了给人家发过去了,觉得不爽了,没有成就感啊,于是贴上来,慰籍一下今天的黑眼圈。
Essential Insights of Living
It was long ago when I heard that phenomenon of suicide was not rear in campus, and at that time I just could not believe it. But, now it is proved to be a hard fact that many youngsters abandon their precious lives before tasting those best things life should offer. This arises my thought on the essential insights of living and the correct way to treat it. There are mainly two reasons which may make some people lose the hope or the passion of their lives and even commit suicide desperately: great sorrow of losing the ones who they love most, or incomparable depress of failure. For the first reason, those ones in the great sorrow of losing loved ones should know that those they loved are not disappear, but merge the individual beings into the universal life, and death is not the end but a begin of another way of existence. Killing one’s self is not a wise way to memorize the dead ones. The only contribution that suicide can make is to depress the living ones, and force the living ones to face a second hurt of losing. For the second reason, the only thing that those who want to murder themselves need is merely positive attitude. The best way to get the hope and passion back is to make their interests gradually wider and more impersonal, until bit by bit the walls of the ego recede, and they will know the meaning of life is not the success but the process to pursue it. Though they are not succeed as they expected, others will carry on what they haven’t finished, and thus their endeavor is not meaningless. In some way, they’ve done contribution to human-beings as whole. The man who, in failure, can see his life in this way, will not suffer from the feeling of desperate. To sum up, suicide is anything but the way to solve problems. As a responsible person, you have too many things to do before you have right to kill yourself: it is your duty to support your parents, to foster your children and to take good care of your spouse. Try to view the things happen around you in a positive way, and surely you will find life is the most treasure gift you’ve ever possess. Enjoy it when you still have chance. June 01 生日礼物过生日了,又老了一岁。今年收到的第一份生日礼物十分特别,与往年决不相同,我猜想大概没有几个人能有我这样得福气,嗯,的确是份以外惊喜:
食堂的牛肉米线里吃来出的马蜂
当时明明没有点“泡汤油炸马蜂”这道菜啊,不知道为什么会收到这么特别的礼物。为了表示自己的惊喜之情,我当即尖叫一声,声震整个学二食堂。若是苍蝇之类,本大小姐一定令它“见怪不怪,其怪自败”,不过马蜂倒还是第一次,正所谓“长江后浪推前浪,一代马蜂换苍蝇”!
奇怪奇怪真奇怪,世界之大无奇不有。喧嚣的食堂,来往的人群,龌龊的饭菜,神秘的马蜂……这里有你想知道的,有你想看到的,有你无法相信的,有你永远都不愿意错过的视听盛宴!
一只聪明善良活泼可爱的马蜂,为何飞到滚烫牛肉米线中,了却它短暂而光辉的一生?食堂的武林高手们使用了何种独家秘笈,逼迫可怜的小马蜂选择米线作为自己的墓场?一个鲜活的生命就此消逝,一碗醇香的牛肉米线就此归于垃圾桶中……惨剧已经酿成,警钟再次鸣响。这是怎样的哀痛者和郁闷者啊!在如此轰轰烈烈的时代背景下,在这般滚滚滔滔的历史洪流中,主题活动“马蜂是如何溺死牛肉米线之中?”拉开帷幕,敬请各位未来柯南.道尔、福尔摩斯们参与破案,破案者将得到一份由天津大学学二食堂特别提供的大奖:带油炸马蜂作佐餐的牛肉米线一碗。奖品有限,先到先得!欢迎大家积极报名,踊跃参加!本次活动的解释权归雪汐斋所有。 May 30 java 传值 vs. 传引用java程序的函数调用到底是传值呢还是传参呢?这可是个难缠的问题,如果搞不清楚还是挺容易出错的:P对于这个问题,最经典的解释莫过于“java函数是传值的,java函数传递的参数是对象的引用”
这两句话好像初听上去有点绕,不过意思倒是表达得蛮精确的。 我看到过几个解释这个问题的例子,不过个人感觉看过例子之后还是只知道是什么不知道为什么,停留在照猫画虎的水平上还是挺容易出问题的。所以举例子之前,先从jvm的实现原理上有个了解应当是不无裨益的。jvm的结构图前一阵子贴到blog上了,那可是从“深入java虚拟机”这本巨牛的书上看来的,绝对有权威性。从jvm的结构图上可以看出来,jvm在实现的时候将属于它的内存分为五部分,其中程序代码(严格的说应当是字节码)是放在java栈的栈帧中,而对象是从堆中分配的,堆这个东西我看可以理解成“对象池”。程序和程序中需要用到的对象放在两个相对独立的区域中,那么程序怎么使用对象呢?答案是程序中真正使用对象的地方其实只是声明了一个对象的引用,也就是把堆中分配了的相应对象的地址放到引用中,栈和堆之间就是通过一个一个的引用来联系的。引用嘛,我理解就是一个指针常量,指针常量又是个什么东西呢?说白了,就是一个无符号整数,这个整数所表达的是引用对象的地址。好了,这下清楚了,不管是基本类型变量(int,float,double什么的)还是对象,相应的内存地址中存放的都是一个数(无符号整数,整数,浮点数等)。传递参数的时候传递的就是相应内存地址中的数,所以说“java函数是传值的”。当然,这个数对于基本类型和对象类型来说意义是不一样的,对于基本类型这个数就是其值本身,传递值的结果就是,改变新的变量的值不影响旧的变量的值;而对于对象来说这个数是它的地址,传递这个值就相当于传递了真实对象的引用,传递了引用或者说是地址的结果就是变化会全局可见,所以又可以说“java函数传递的参数是对象的引用”。
唔,松口气啦。经过上面这一小堆讨论,不难理解为什么java在传递参数时对于基本类型和对象表现不同:)
现在开始举例了,举网上搜来的例子,看看是不是比原来没有上面的解释的时候好理解一点?
public class TestRef
{ public static void main(String[] args) { ValueObject vo1 = new ValueObject("A", 1); System.out.println("after vo1: " + vo1.getName()); //=A changeValue1(vo1); System.out.println("after changeValue1: " + vo1.getName()); //=A1, changed changeValue2(vo1); System.out.println("after changeValue2: " + vo1.getName()); //=A1, changeValue2内部的赋值不会影响这里。 } /** * 使用vo1自身的函数对其内部数据进行改变是有效的,函数外可反映出来, * 因为这是对对象本身的操作
* 这种object称为可变的(mutable) * @param vo1 */ private static void changeValue1(ValueObject vo1) { vo1.setName("A1"); } /** * 在函数内给vo1重新赋值不会改变函数外的原始值,因为这种改变了引用的指向 * @param vo1 */ private static void changeValue2(ValueObject vo1) { vo1 = new ValueObject("B", 2); System.out.println("inside changeValue2: "+ vo1.getName()); //=B,赋值操作引起的结果变化仅在changeValue2内部有效 } } class ValueObject { public ValueObject() {} public ValueObject(String name, int id) { this.name = name; this.id = id; } private String name; private int id; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } java中对象的每个实例(就是对象)内存地址是唯一的,它一旦被创建,能够对这个地址进行操作的就是其本身,如果ValueObject类中没有public void setName之类的方法对这个类的实例中的数据进行修改的话,程序是没有任何别的方法可以修改ValueObject类的实例中的数据,这个就是java的封装特性。对于不提供修改内部数据的方法的类,我们称为不可变(immutable)的类。在函数中对传入的参数变量进行赋值操作,只能在函数范围内改变局部变量指向的引用地址,但是不会改变原始地址的内容。因此,在changeValue2(...)函数内部的vo1和函数外的vo1虽然名字相同,但是实际上是不同的实例变量,只不过指向了和函数外的vo1同样的地址,所以当我们用vo1=... 对其进行赋值的时候,只不过是把函数内的临时变量指向了新的地址,并没有改变原始vo1内存地址中的内容。这就是在运行changeValue2(...)之后,vo1的值在main范围内仍然没有被修改的原因。而changeValue1里面是调用的ValueObject本身的function来更改其内容,因此是原始内存地址中的数据被更改了,所以是全局有效的. 总结: 对于引用类型的传参也是传值的,传的是引用类型的值,其实就是对象的地址。 1. java参数传递值的。 2. java所有对像变量都是对像的引用。 不知道我解释清楚没,要是还是不能理解java参数传递的原理,强烈推荐看看“深入java虚拟机”一书的第五章,中文翻译的不是特别出色,可以看看英文原版,应该比中文版好懂:) May 29 盘山走马西来欲到天
去过长城的第二天又去了盘山,一直以为盘山就是个小山包,看了这张导游图才知道这趟旅行的任务并不轻松。
相传三国曹魏时田畴隐居于此,亦称田盘山。一入此处,想必是胜景在前,物华天宝、人杰地灵。引得乾隆慨言“早知有盘山,何必下江南 ” 。
山光悦鸟性,潭影空人心
山水相辉,楼台相映,天予安排
野芳发而幽香,佳木秀而繁阴
五峰、八石、三盘、七十二寺、十三塔
试上最高处闲坐地,东,也在图画里,西,也在图画里
大肚能容,容天下难容之事
笑口常开,笑世上可笑之人 疏篱曲径田家小,云树开清晓
会当临绝顶
一览众山小 连峰去天不盈尺
枯松倒挂依绝壁 别来几向梦中看
蓟门长城长城谣 其实很小的时候就听过蓟门关的大名,记得好像唐朝有个叫祖咏的还写了首叫做《望蓟门》的,赞美这里“燕台一望客心惊,箫鼓喧喧汉将营。万里寒光生积雪,三边曙色动危旌。沙场烽火连胡月,海畔云山拥蓟城。少小虽非投笔吏,论功还欲请长缨。”那个时候很喜欢他的最后两句,向往蓟门的“海畔云山”,“万里寒光”。只是一直没有想到大名鼎鼎的蓟门就是今天天津的蓟县。蓟县有长城,名曰黄崖关,位于北京之东,天津之北,居于蓟北部群山之中,黄崖关地处北京、天津、唐山、承德的正中间,自古为兵家必争之地,又是北部之敌进犯京都的要冲,祖咏的短短几言道尽蓟门无限风光和无可取代的军事地位。
东方欲晓,莫道君行早,风景这边独好。
城堞远望如刀齿,咬定青天不放松。 隆庆二年(公元1568年),明政府下令任命戚继光总理蓟州、昌平、辽东、保定军务。 抗击倭寇,修筑长城,戚继光将军用他的铮铮铁骨写下又一首永恒的诗篇。岳飞曾经慨然道“三十功名尘与土,八千里路云和月”,戚继光有何曾不是怀着这样一种“待从头收拾旧山河”的热忱?他日日横戈马上,用全部生命为家国而战斗。“南北驱驰报主情 江花边草笑平生 一年三百六十日 都是横戈马上行”
拾级而上,都倍感吃力,可想当年筑城的艰辛。长城的每一块沉重的石头砖块都用手搬、肩扛、背驮上去。一万两千七百里的长城呵,承载了中华民族多少血泪辛酸?孟姜女哭长城,千古绝唱谁人听……
残破的长城见证了中华民族几千年来抗击外族侵略的决心,当刀光剑影已经黯淡,鼓角争鸣离我们远去,后人能否记得为了民族的繁衍生息而逝去的先辈?“誓扫匈奴不顾身,五千锦貂丧胡尘。可怜无定河边骨,犹是春闺梦里人。”长城角下有几多白骨,几多不屈的魂灵?
无路请缨,等终军之弱冠
有怀投笔,慕宗悫之长风 表里山河
长城拱身拧体,利爪牢牢抓住山的脊梁,盘垣卓立,与雄浑的山势构成一派凶险的气象。
离着黄崖关长城不远处蓟县城内就有乾隆皇帝的行宫。一边是边疆战士“岁岁金河复玉关,朝朝马策与刀环”,远离家园在苦寒的塞外流血战斗,另一边却是帝王“朝朝玉树后庭花,步步金莲潘丽华”,穷奢极欲挥金如土荒淫无度;一边是疆场之上“髑髅皆是长城卒,日暮沙场飞作灰”,另一边却是宫闱之内“凤阁龙楼连霄汉,碧树琼枝作烟罗”。
保家卫国,战争没有停止过。“辞凤阁,盼滦河,别离此情将奈何?羽盖峨峨,虎皮驮驮,雁远暮云阔…”昭君出塞了,留下满路的驼铃,然而修好只是暂时,不多久风烟又起;我们的祖先曾让胡人有过“北斗七星高,哥舒夜带刀。至今窥牧马,不敢过临洮”的胆战心惊;也留下了“遗民泪尽胡尘里,南望王师又一年”的凄凉悲歌。
城上城下争战了一部历史,多少个隘口就有多少次的悲欢,你永远是个无情的建筑 ,蹲踞在荒莽的山巅 ……
离开的时候正是日暮,想起一首歌
狼烟起江山北望
龙起卷马长嘶剑气如霜 心似黄河水茫茫 二十年纵横间谁能相抗 恨欲狂长刀所向 多少手足忠魂埋骨它乡 何惜百死报家国 忍叹惜更无语血泪满眶 马蹄南去人北望 人北望草青黄尘飞扬 我愿守土复开疆 堂堂中国要让四方 来贺 May 26 约瑟夫问题的java实现讲讲这个Josephus游戏的故事先:据说著名的犹太史学家Josephus有过以下故事,在罗马人占领乔塔帕特后,39个犹太人与Josephu和他的朋友躲到一个洞中,39个犹太人决定宁愿死夜不愿被敌人俘虏,于是决定了一个自杀的方式,41个人排成一个圆圈,由第1个人开始报数,每报到第3人该人就必須自杀,然后再由下一个人重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从,Josephus要他的朋友先假裝遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
今天又看到josephus问题觉了,总觉得会有一种简单的办法来解决这个问题,可以既不使用链表又不用struct和多维数组什么的,呵呵,结果真的找到了,下面这个就是了
public class Josephus
{ public static void main(String args[]) { if(args.length != 2) //处理参数数目不正确情况 { System.out.println("Please Input a number!"); return; } int i, j, n, m; n = Integer.parseInt(args[0]); m = Integer.parseInt(args[1]); if (n <= 0 || m <= 0) //处理参数值不正确的情况 { System.out.println("Paramter must bigger than zero!"); return; } int a[] = new int[n]; for (i = 0; i < n; i++) a[i] = i + 1; int k = 1; //标识处理第k个离开的人 i = -1; //数组下标,下一个为0,即第一个人 while (true) //k等于n表示只剩下一个人了 { for (j = 0; j < m;) //在圈中数m个人 { i = (i + 1) % n; if (a[i] >0) j++; //a[i] >0表示第i个人还没有离开 } if(k==n) break; System.out.println("No." + a[i] + " is out!"); a[i] = -1; //表示该人离开 k++; } System.out.println("No." + a[i] + " is the winner!"); } } 输入:
C:\Documents and Settings\circle\桌面>java Josephus 9 4
输出结果:
No.4 is out! No.8 is out! No.3 is out! No.9 is out! No.6 is out! No.5 is out! No.7 is out! No.2 is out! No.1 is the winner! 运行速度比较快,输入java Josephus 1,000,000 9(也就是说有一百万个人排成一圈,每隔9个出局一个),程序只需要两三秒钟就可以得到最后的winner:No. 963295,当然,要是输出"No." + a[i] + " is out!"这句就很花时间了。
ps:刚才在网上搜到一个更强的,c程序,只有8行!!!暴快!!!汗一下……
用的是倒推法,而不是向上面那样模拟游戏的方法。
#include <stdio.h> main() { int n, m, i, s=0; printf ("N M = "); scanf("%d%d", &n, &m); for (i=2; i<=n; i++) s=(s+m)%i; printf ("The winner is %d\n", s+1); } 求X个的质数,嗯,这个算法好简洁 算法P:
求X个不同的质数,PRIME[]为一个数组,存储所有求得的质数
P1. [初始化]PRIME[1]<-2, N<-3, J<-1(N跑遍所有奇数,因为只有奇数可以成为质数 的候选者;J用来标记至今已找到多少个质数)
P2. [N是质数]置J<-J+1, PRIME[J]<-N P3. [找到X个?]若J=X,则全部要求的质数找到,退出程序 P4. [增加N]置N<-N+2 P5. [K<-2]置K<-2(PRIME[K]将跑遍N的所有可能的质因子) P6. [K/PRIME[K]?]以PRIME[K]除K;设Q是商,R是余数,若R=0(因此N不是质数),转 向P4
P7. [PRIME[K]足够大了?]若Q<=PRIME[K],则转P2(在这种情况下,N必然是质数) P8. [增加K]K加1,并转P6 算法来自The Art of Programming,的确是大师,窥一斑而见全豹,就这么个小东西都能看出来人家的厉害之处,我以为求N是不是质数就要一个一个挨个除到N的平方根呢,这个方法可快多了。 May 25 交换变量a和b不引入变量c算法Change:
变量a和b交换,一般要引入第三个变量c:
c=a;
a=b;
b=c;
其实变量c没有什么实质性的作用,只是作为一个“中转站”出现。如果不想引入变量c而完成交换,可以通过以下方法实现: a = a + b; b = a - b; a = a - b; 或者使用位运算符“异或” a = a ^ b; b = a ^ b; a = a ^ b; May 22 Java虚拟机结构图《深入java虚拟机》看完了,挺难理解的,不是很懂,嘿嘿,这个自然了。虽然他的大部分思想还是很自然也挺符合人们的思维习惯的,但是毕作为一个先进的技术它的深层原理和具体技术还是不那么显而易见的,远远超出了我仅有的理解能力:P不懂的实在比不懂的多得多,不过上面那幅图倒是让我明白了点JVM底层的实现机制,受益匪浅。很多以前很诧异理解不了的语法和概念在仔细研究了这幅图之后变得清晰起来。
执行引擎处于JVM的核心位置,在Java虚拟机规范中,它的行为是由指令集所决定的。尽管对于每条指令,规范很详细地说明了当JVM执行字节码遇到指令时,它的实现应该做什么,但对于怎么做却言之甚少。Java虚拟机支持大约248个字节码。每个字节码执行一种基本的CPU运算,例如,把一个整数加到寄存器,子程序转移等。Java指令集相当于Java程序的汇编语言。
由于指令系统的简单性,使得虚拟机执行的过程十分简单,从而有利于提高执行的效率。指令中操作数的数量和大小是由操作符决定的。如果操作数比一个字节大,那么它存储的顺序是高位字节优先。例如,一个16位的参数存放时占用两个字节,其值为: 第一个字节*256+第二个字节字节码。
指令流一般只是字节对齐的。指令tableswitch和lookup是例外,在这两条指令内部要求强制的4字节边界对齐。
未完,待续 May 21 多处理器系统中Cache一致性解决方案PART 1 软件解决方案
软件解决方案是由编译器和操作系统解决一致性问题。这种解决方案将开销由运行时转到了编译时,设计复杂性由硬件转到软件。然而,软件方法倾向于使用保守判定,因为软件方法通过分析代码确定缓存共享变量的安全时段,任何共享变量只要处于非安全期就不允许任何存储器缓存它。当然这样就造成了不必要的开销,这种开销的大小是通过高速缓存利用率差来反映的。
PART 2 硬件解决方案
硬件解决方案在运行时动态识别潜在问题,提高高速缓存的利用率,并且硬件方案可以确保高速缓存一致性的问题对程序员透明。
硬件解决方案通常有两种:目录协议和监听协议。
在目录协议中, 所有的请求都对照目录进行检查,需要执行某些传输操作。而存放目录的硬件设备就有可能成为整个系统的瓶颈。通常这种协议在采用复杂互联方案的大型系统中有效。 监听协议把高速缓存一致性责任分布到每个高速缓存控制器上,每个高速缓存通过特定得方式识别被共享的数据块,并且将其更新过的操作通知到其他高速缓存。这种协议适合于居于总线的多处理器系统。
MESI协议属于监听协议中的写无效协议。MESI协议MESI协议是“修改(modified)、排它(exclusive)、共享(shared)、无效(invalid)”四个功能的简称,每个缓存模块必须按照MESI协议完成这4个独立的功能。
● 修改:如果某一内存数据区记录只存在于一个CPU缓存中,那么此CPU可以对此数据进行修改,而无需通知其他CPU。 ● 排它:同一时间只能有一个CPU对同一内存数据区进行修改或者更新。 ● 共享:如果某一内存数据区记录存在于多个CPU缓存中,那么CPU对此数据修改后,必须通知其他CPU。 ● 无效:一旦CPU对缓存数据访问失效,那么就必须重新从内存中读取数据。 这种协议要求在任何时刻都可以有多个读者,但至多有一个写者。当请求写操作时,其他缓存中的这个数据块被置为失效状态。在其他处理器访问该数据块之前,执行写操作的处理器以独占的方式访问该数据块。
另外还有一种写更新的协议,多个处理器读,多个处理器写,更新的内容被分发到所有其他处理器。这种方式的代价比较高。 垃圾收集的算法Java的堆是一个运行时数据区,类的实例(对象)从中分配空间。Java虚拟机(JVM)的堆中储存着正在运行的应用程序所建立的所有对象,这些对象通过new、newarray、anewarray和multianewarray等指令建立,但是它们不需要程序代码来显式地释放。一般来说,堆的是由垃圾回收来负责的,尽管JVM规范并不要求特殊的垃圾回收技术,甚至根本就不需要垃圾回收,但是由于内存的有限性,JVM在实现的时候都有一个由垃圾回收所管理的堆。垃圾回收是一种动态存储管理技术,它自动地释放不再被程序引用的对象,按照特定的垃圾收集算法来实现资源自动回收的功能。
垃圾收集的意义
我最不喜欢“意义”这两个字了,可能是政治背多了,一见“意义”脑袋都大成俩了,垃圾收集当然是有意义的,没意义设计JVM的人也就不会多次一举了。不过说说这个垃圾回收是干吗使的也有点用,我勉强东拼西凑了这点东西,凑合看看。
在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象(C++是我的nightmare,写C的程序的时候我就经常因为这类问题搞得狼狈不堪,我始终对会用C++的人高山仰止);而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾。JVM的一个系统级线程会自动释放该内存块。垃圾收集意味着程序不再需要的对象是"无用信息",这些信息将被丢弃。当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用。事实上,除了释放没用的对象,垃圾收集也可以清除内存记录碎片。由于创建对象和垃圾收集器释放丢弃对象所占的内存空间,内存会出现碎片。碎片是分配给对象的内存块之间的空闲内存洞。碎片整理将所占用的堆内存移到堆的一端,JVM将整理出的内存分配给新的对象。垃圾收集能自动释放内存空间,减轻编程的负担。GC使Java 虚拟机具有一些优点。首先,它能使编程效率提高。在没有垃圾收集机制的时候,可能要花许多时间来解决一个难懂的存储器问题。在用Java语言编程的时候,靠垃圾收集机制可大大缩短时间。其次是它保护程序的完整性, 垃圾收集是Java语言安全性策略的一个重要部份。 当然,使用这么省事的功能是需要付出代价滴,垃圾收集本身就挺耗费资源的,它的开销影响程序性能(鱼和熊掌不能兼得,反正一般情况下也不用Java做实时性很强的程序,慢一点我忍了)。Java虚拟机必须追踪运行程序中有用的对象, 而且最终释放没用的对象。这一个过程需要花费处理器的时间。其次垃圾收集算法的不完备性,早先采用的某些垃圾收集算法就不能保证100%收集到所有的废弃内存。随着垃圾收集算法的不断改进以及软硬件运行效率的不断提升,这些问题没准一夜之间迎刃而解。
垃圾收集的算法分析
Java语言规范没有明确地说明JVM使用哪种垃圾回收算法,但是任何一种垃圾收集算法一般要做2件基本的事情:(1)发现无用信息对象;(2)回收被无用对象占用的内存空间,使该空间可被程序再次使用。大多数垃圾回收算法使用了根集(root set)这个概念;所谓根集就量正在执行的Java程序可以访问的引用变量的集合(包括局部变量、参数、类变量),程序可以使用引用变量访问对象的属性和调用对象的方法。垃圾收集首选需要确定从根开始哪些是可达的和哪些是不可达的,从根集可达的对象都是活动对象,它们不能作为垃圾被回收,这也包括从根集间接可达的对象。而根集通过任意路径不可达的对象符合垃圾收集的条件,应该被回收。
几个常用的算法
1、 引用计数法(Reference Counting Collector) 引用计数法是唯一没有使用根集的垃圾回收得法,该算法使用引用计数器来区分存活对象和不再使用的对象。一般来说,堆中的每个对象对应一个引用计数器。当每一次创建一个对象并赋给一个变量时,引用计数器置为1。当对象被赋给任意变量时,引用计数器每次加1。当对象出了作用域后(该对象丢弃不再使用),引用计数器减1,一旦引用计数器为0,对象就满足了垃圾收集的条件。基于引用计数器的垃圾收集器运行较快,不会长时间中断程序执行,适宜地必须 实时运行的程序。但引用计数器增加了程序执行的开销,因为每次对象赋给新的变量 ,计数器加1,而每次现有对象出了作用域生,计数器减1。 2、 tracing算法(Tracing Collector) tracing算法是为了解决引用计数法的问题而提出,它使用了根集的概念。基于tracing算法的垃圾收集器从根集开始扫描,识别出哪些对象可达,哪些对象不可达,并用某种方式标记可达对象,例如对每个可达对象设置一个或多个位。在扫描识别过程中,基于tracing算法的垃圾收集也称为标记和清除(mark-and-sweep)垃圾收集器. 3、 compacting算法(Compacting Collector) 为了解决堆碎片问题,基于tracing的垃圾回收吸收了Compacting算法的思想,在清除的过程中,算法将所有的对象移到堆的一端,堆的另一端就变成了一个相邻的空闲内存区,收集器会对它移动的所有对象的所有引用进行更新,使得这些引用在新的位置能识别原来 的对象。在基于Compacting算法的收集器的实现中,一般增加句柄和句柄表。 4、 coping算法(Coping Collector) 该算法的提出是为了克服句柄的开销和解决堆碎片的垃圾回收。它开始时把堆分成 一个对象 面和多个空闲面, 程序从对象面为对象分配空间,当对象满了,基于coping算法的垃圾收集就从根集中扫描活动对象,并将每个 活动对象复制到空闲面(使得活动对象所占的内存之间没有空闲洞),这样空闲面变成了对象面,原来的对象面变成了空闲面,程序会在新的对象面中分配内存。一种典型的基于coping算法的垃圾回收是stop-and-copy算法,它将堆分成对象面和空闲区域面,在对象面与空闲区域面的切换过程中,程序暂停执行。 5、 generation算法(Generational Collector) stop-and-copy垃圾收集器的一个缺陷是收集器必须复制所有的活动对象,这增加了程序等待时间,这是coping算法低效的原因。在程序设计中有这样的规律:多数对象存在的时间比较短,少数的存在时间比较长。因此,generation算法将堆分成两个或多个,每个子堆作为对象的一代(generation)。由于多数对象存在的时间比较短,随着程序丢弃不使用的对象,垃圾收集器将从最年轻的子堆中收集这些对象。在分代式的垃圾收集器运行后,上次运行存活下来的对象移到下一最高代的子堆中,由于老一代的子堆不会经常被回收,因而节省了时间。 6、 adaptive算法(Adaptive Collector) 在特定的情况下,一些垃圾收集算法会优于其它算法。基于Adaptive算法的垃圾收集器就是监控当前堆的使用情况,并将选择适当算法的垃圾收集器。
几点补充
嘿嘿,下面这特点总结得够拽,我是写不出来滴,这要相当的总结能力,文学水平。人家说中国的科研人员不一定能成为科学家,但肯定能成为文学家。
(1) 垃圾收集发生的不可预知性:由于实现了不同的垃圾收集算法和采用了不同的收集机制,所以它有可能是定时发生,有可能是当出现系统空闲CPU资源时发生,也有可能是和原始的垃圾收集一样,等到内存消耗出现极限时发生,这与垃圾收集器的选择和具体的设置都有关系。 (2) 垃圾收集的精确性:主要包括2 个方面:(a)垃圾收集器能够精确标记活着的对象;(b)垃圾收集器能够精确地定位对象之间的引用关系。前者是完全地回收所有废弃对象的前提,否则就可能造成内存泄漏。而后者则是实现归并和复制等算法的必要条件。所有不可达对象都能够可靠地得到回收,所有对象都能够重新分配,允许对象的复制和对象内存的缩并,这样就有效地防止内存的支离破碎。 (3) 现在有许多种不同的垃圾收集器,每种有其算法且其表现各异,既有当垃圾收集开始时就停止应用程序的运行,又有当垃圾收集开始时也允许应用程序的线程运行,还有在同一时间垃圾收集多线程运行。 (4) 垃圾收集的实现和具体的JVM 以及JVM的内存模型有非常紧密的关系。不同的JVM 可能采用不同的垃圾收集,而JVM 的内存模型决定着该JVM可以采用哪些类型垃圾收集。现在,HotSpot 系列JVM中的内存系统都采用先进的面向对象的框架设计,这使得该系列JVM都可以采用最先进的垃圾收集。 (5) 随着技术的发展,现代垃圾收集技术提供许多可选的垃圾收集器,而且在配置每种收集器的时候又可以设置不同的参数,这就使得根据不同的应用环境获得最优的应用性能成为可能。
写程序时要注意的东西,这个才是我最关心的东西,吼吼: (1) 不要试图去假定垃圾收集发生的时间,这一切都是未知的。比如,方法中的一个临时对象在方法调用完毕后就变成了无用对象,这个时候它的内存就可以被释放。 (2) Java中提供了一些和垃圾收集打交道的类,而且提供了一种强行执行垃圾收集的方法--调用System.gc(),但这同样是个不确定的方法。Java 中并不保证每次调用该方法就一定能够启动垃圾收集,它只不过会向JVM发出这样一个申请,到底是否真正执行垃圾收集,一切都是个未知数。 (3) 挑选适合自己的垃圾收集器。一般来说,如果系统没有特殊和苛刻的性能要求,可以采用JVM的缺省选项。否则可以考虑使用有针对性的垃圾收集器,比如增量收集器就比较适合实时性要求较高的系统之中。系统具有较高的配置,有比较多的闲置资源,可以考虑使用并行标记/清除收集器。 (4) 关键的也是难把握的问题是内存泄漏。良好的编程习惯和严谨的编程态度永远是最重要的,不要让自己的一个小错误导致内存出现大漏洞。 (5) 尽早释放无用对象的引用。大多数程序员在使用临时变量的时候,都是让引用变量在退出活动域(scope)后,自动设置为null,暗示垃圾收集器来收集该对象,还必须注意该引用的对象是否被监听,如果有,则要去掉监听器,然后再赋空值。结束语 一般来说,Java开发人员可以不重视JVM中堆内存的分配和垃圾处理收集,但是,充分理解Java的这一特性可以让我们更有效地利用资源。同时要注意finalize()方法是Java的缺省机制,有时为确保对象资源的明确释放,可以编写自己的finalize方法 Java程序内存泄露问题1. java中的“ 垃圾收集器”的原理 GC的功能是当发现一个对象不再需要被使用时,将它删除,同时将其占有的内存归还给JVM或系统。那么,GC又是如何来判断一个对象已经不再需要呢?它的标准是当该对象没有被引用(Reference)就表明是不再被需要的。GC会从根节点开始遍历被Java应用程序的整个生命周期中始终存在的那些类,所有被引用的对象将被标记,没有标记的当作垃圾被收集。所以,当内存足够时,JVM 是不会启动GC 的,也不会暴露内存泄露问题的严重程度。
2. 内存是如何被泄露的 例:Class_A首先生成了一个实例A,并且该实例在整个程序中都将被使用。然后程序生成了Class_B的一个实例,该实例可能只是被使用过一次两次。如下: Class_A = new Class_A(); … Class_B = new Class_B(); A.referB = B; …
如果A使用完B以后没有清空该引用,则将一直保持对B的引用,即使以后再也不需要B了。在这种情况下B是不可能被删除的。 解决问题十分简单:在应用程序中增加清除引用B的语句:A.referB = null;,即可。现在GC当然会轻松地找到泄露内存的B并收集由它占着的许多重复内存,从而解决异常终止的问题。
3 以上的话总结起来就是“概括地说,内存托管语言中的内存泄漏产生的主要原因:保留下来却永远不再使用的对象.
嘿嘿,鼓励一下自己,很努力的写这篇帖子,尤其是那个小图,画的很辛苦的说,感觉是把问题说清楚了,鼓掌鼓掌^_^ java upcastingabstract class HumanBeing { String name; public HumanBeing() { show(); } public abstract void show(); } class Man extends HumanBeing { public Man(String name) { this.name=name; } public void show() { System.out.println("I am a man..."); System.out.println("My name:"+this.name); } } class Woman extends HumanBeing { public Woman(String name) { this.name=name; } public void show() { System.out.println("I am a woman..."); System.out.println("My name:"+this.name); } } public class UpCasting { public static void showCharacteristics(HumanBeing human) { human.show(); } public static void main(String[] args) { showCharacteristics(new Man("liansen")); showCharacteristics(new Woman("shorwan")); } }
执行结果: >java UpCasting I am a man... My name:liansen I am a woman... My name:shorwan 刚才那篇古文的现代汉语解释 传说翻译完这篇古文,那个中文博士疯掉了……
据说那个射死了9个太阳的后羿留下了一个名字叫熠的后裔,
熠居住在彝族人的地盘上面,
所谓“不为良相则为良医“,鉴于祖先不积德连恒星都敢破坏,
估计自己当良相比较渺茫,
于是决定从医,
在杏林中素有义医之称,
其实就是帮人看了病但是病人不给钱,
而他寄人篱下不敢逼债只好作罢,
这样的事发生多了,
自然那些没有给钱却又被医好的人为了平衡心理就送了他这个反正不用出钱的称
号.不过客观地讲,
熠在医学上面还是很有造诣的.
熠的姨妈不幸病死了,
留下了一个女儿叫做伊,
伊真是名如其人,
大有众多诗词中咏唱的“伊人“般的梦幻色彩,
不但仪态万方风情万种,
而且穿着打扮很有品味犹如仙人下凡,
更加让人惊讶的是她气质极佳神采奕奕,
恐怕是能够迷死上帝.
真可谓: 伊人
长空酒冷我独倚,
一睹佳人心飘逸.
踏出蛮夷生双翼,
摘星捞月只为伊.
熠不由自主地爱上了伊, 在那个婚姻法还不健全的年代,
表哥表妹的关系就像当今学校里面异性的同桌关系一样暧昧.
熠开始他的追求战略,
首先因为伊喜欢买衣服,
所以熠送了一件非常奢华漂亮的衣服给伊,
当然直接导致的结果是熠在下个季度中都吃不上荤.
伊看都没有看一眼就把熠买给她的衣服丢给了一个衣不蔽体的丐帮弟子.
不但这样,
伊还穿上一件自己买的新衣服,
伊用这种方式向熠透露出了她的“love message“翻译成现代语言就是:“你丫想追
我,这辈子多积德,看看下辈子有没有机会吧.“
熠顿时郁闷.
可算是: 伊之意
杏林驰骋为良医,
愿弃功名遂伊意.
可怜佳人不恋熠,
衣带迤旖常追忆.
伊为了躲避熠的追求倍感尴尬,
不能够老是装手机没电不能回短信,上次慌称卡上没钱被熠自做多情充值之后,
伊决定还是到一个永远不在服务区的地方比较安全.
于是她悄悄地逃到了一个叫“邑“的地方.
熠这样的人也听可怜的,
追MM追到MM都远走他乡躲开他,
不过伊也很可怜,
被一个自己永远不可能爱上的人爱上也是痛苦.
那天天气很热,
伊游弋到了一棵树下阴凉的地方看到有人在下棋,
她一时手痒,
就和一个叫毅的人下了起来.
话说那个毅可谓是高大威猛玉树临风,
一副逍遥不羁的浪人打扮,
毅在下棋的过程中不断地指点伊,
伊不由得对毅在下棋上面的造诣佩服不已,
感觉到了一种发自肺腑的高兴,
那颗少女的芳心一不小心就被毅俘获了.
当然,
与此同时,
毅也死心塌地陷入了情花的谜团中.
第二天,
天刚朦朦亮,
伊就来到那棵树下,
那里已经有一盘棋为她摆好了.
两人开始了棋局上的厮杀,棋盘之上的两人的眼神已经纠缠在了一起.
毅身边徘徊着他的宠物:一只蜥蜴,
它也嗅到了空气中缠绵的气味,在高兴地摇着尾巴.
时间非常配合相对论,
不知不觉又到了两人告别之时,
毅拾起蜥蜴送给了伊,
伊也把随身带来的一件昨天熬夜为毅制作的衣服送给了毅.
让人感慨道: 爱情的坚毅
骏马有眷念草原的情意
大海一直渴望吻到飞鸟的双翼
青春在洋溢
亚当和夏娃的后裔
披上了恋人织就的新衣
一样会感染上爱情的瘟疫
哪怕只能够得到一段会渐渐褪色的回忆
我也要追逐那心灵片刻的安逸
也许是上帝嫉妒了这对恋人,
也许是佛主觉得不经过风波修炼的感情是对不起观众的,
总之紧接着短暂快乐之后的是无情的病魔-----伊病倒了,
开始昏迷不醒,
在迷糊之时她一直呼唤着毅的名字,
看到伊倚靠着一把椅子咿咿地说着胡话,
毅也泣不成声了.
唯一的希望就是去找熠,
毅听伊说过熠是一位医术造诣很深的名医,
也许熠能够救好伊.
于是毅来到了熠的家里,
把伊的情况告诉了熠,
并且恳求熠去邑帮伊治病.
熠听了这些先是脸上流露出紧张的表情,
当想起伊对他的无情他咬了咬牙,
心中在徘徊着要不要替眼前这个人做嫁衣裳,
渐渐地,
撒旦的表情出现了.
熠对毅说到:“要我去救伊,可以,不过我治好伊之后,你要发誓远走高飞永远都不能
够见伊.“
为什么上天总要人们在两种为难的选项中作选择呢?
毅最后痛苦地做出了抉择(这也是作者丝竹逍遥的选择):
世界上最重要的事情是我所爱的人的幸福,
只要她能够幸福,
在她的世界里面出不出现我自己都已经不重要了.
毅想到了只有熠才能够救伊,
熠是一个很实际的人而自己只是一个擅长下棋的满脑子理想主义的浪人.
毅将背上的棋板取下来,重重地摔在地上,留着眼泪说出了违心的誓言.
踏着熠的狞笑,
毅走进了漫天的黄沙中.
熠来到了邑,
经过初步诊断伊是胰脏出现了疮痍,
熠马上给伊服用了用蚂蚁制成的独门秘方,
伊服用之后立即出现腹泻,
将肚中的毒素排除了体外,
并且开始神志清醒,
发出了咦咦的声音.
紧接着熠割下了薏米制药,
给伊服用,
很快伊就康复了.
伊一直非常想念毅,
甚至昏迷的时候都在叫着毅的名字,
伊身体一好转,
没有挤出一丝笑容给熠,
就质问伊毅到哪里去了,
伊佯装一副惋惜状说毅已经决定离开伊再不回来了
伊不相信,长声叹息,终于自缢而亡。
而熠因心中不安,也追随伊自缢了。 呵呵,史上最bt的古文 前两天看了一点点关于中文分词技术的文章,汉语分词真的是个很不好攻克的技术难题啊,不管是baidu还是google的分词做得都不算尽如人意。 嘿嘿,想看看分词程序哪一天才能做到读懂这篇一“yi”到底的古文的程度。搞人工智能的大侠们加油吧,希望我这辈子还有希望看到。
羿裔熠①,邑②彝,义医,艺诣.
熠姨遗一裔伊③,伊仪迤,衣旖,异奕矣.
熠意④伊矣,易衣以贻伊,伊遗衣,衣异衣以意异熠,熠抑矣.
伊驿邑,弋一翳⑤,弈毅⑥.毅仪奕,诣弈,衣异,意逸.毅诣伊,益伊,伊怡,已臆⑦毅矣,毅亦怡伊.
翌,伊亦弈毅.毅以蜴贻伊,伊亦贻衣以毅.
伊疫,呓毅,癔异矣,倚椅咿咿,毅亦咿咿.
毅诣熠,意以熠,议熠医伊,熠懿⑧毅,意役毅逸.毅以熠宜伊,翼逸.
熠驿邑以医伊,疑伊胰痍⑨,以蚁医伊,伊遗异,溢,伊咦.熠移伊,刈薏⑩以医,伊益矣.
伊忆毅,亦呓毅矣,熠意伊毅已逸,熠意役伊.伊异,噫,缢.
熠癔,亦缢
①熠:医生,据说为后羿的后裔.
②邑:以彝为邑,指居住在一个彝族聚居的地方.
③伊:绝世佳丽,仪态万方,神采奕奕.
④意:对伊有意思,指熠爱上了伊.
⑤翳:有遮蔽的地方,指伊游弋到了一个阴凉的地方.
⑥毅:逍遥不羁的浪人,善于下棋,神情坚毅,目光飘逸.
⑦臆:主观的感觉,通“意“,指对毅有好感.
⑧懿:原意为“懿旨“,此处引申为要挟,命令.
⑨胰痍:胰脏出现了疮痍.
⑩刈:割下草或者谷物一类.薏:薏米,白色,可供食用,也可入药. 史记 马家爵列传 马君加爵者,桂之宾阳人也。形貌古异,环眼蒜鼻,发尽上指。为人罕言语,工技击,多膂力。年及弱冠,入滇之官学。
网上偶见此篇,不禁为之绝倒,不知哪位仁兄,确有史记遗风,尤是一段太史公赞不可不谓绝妙。 Nostalgia Chinese is famous for their nostalgia. They gain this special character from their culture and tradition. Chinese, savoring tradition, are deeply tied to, or at least mentally tie to specific locations. Place Vs. SpacePlace and Space The cultural differences have existed for thousands of years. If one looks into the differences between Chinese culture and American culture and focuses on the concept of space and location, he will see those diversities more clearly. Americans are less rooted to place and are future oriented, while Chinese, savoring tradition, are deeply tied to, or at least mentally tie to specific locations. Just as Dr. Philip C. Holtrop said, America has a frontier culture and China has a land culture. “Geographical mobility has been high (oceans, land, even to the moon).” However, Chinese always have nostalgia lingering in their minds. Americans have a sense of space, not of place. Visiting an American home in exurbia, almost the first thing the guest does is drift toward the picture window. It is hand for a Chinese to understand that the first compliment the guest is expected to pay his host inside the house is to say how lovely it is outside the house. The host is pleased that his guest should admire his vista. The distant horizon is not merely a line separating earth from sky; it is a symbol of the future. The American is not rooted in his place, no matter how lovely it is. His eyes are drawn by the expanding space to a point on the horizon, which means future to him. By contrast, a traditional Chinese home always has walls enclose it. Stepping behind the spirit wall, one is in a courtyard with perhaps a little garden around a corner. Once inside of a typical traditional Chinese house, one is wrapped in an air of calm beauty, an ordered world of buildings, pavement, rocks, and decorative flowerbed. But one cannot have a distant view: nowhere does space open out before him. The only open space is the sky above. In Chinese belief, if every thing in a garden or courtyard can be taken at one glance, it will be uninteresting. Chinese is rooted in his place. Once he settles down, he won’t move for a relatively long time. Chinese are loyal to the place they live in. A Chinese changes his living place only when there is special serious reason. Chinese have gained this special character from their belief of Confucian and Taoism. Influenced by Confucian and Taoism, Chinese never had a strong, national wide religion throughout their five-thousand-year civilization. The gods they respected were their ancestors. They believed that their ancestors would bless and protect them as long as they enshrined and worship their ancestors and lived at their original place. As a country emphasized agriculture a lot in the past thousands of years, the Chinese tie to place is deeply felt. The Taoist classic Tao Te Ching captures the ideal of rootedness in place with these words: “though there nay be another country in the neighborhood so close that they are within sight of each other and the crowing of cocks and barking of dogs in one place can be heard in the other, yet there is no traffic and communication between them; and throughout their lives the two peoples have noting to do with each other.” Farmers had ranked high in China in feudalistic society. The reason is not only that they are engaged in a “root” industry of producing food but that, unlike pecuniary merchants, they are tied to the land and do not abandon their country when it is in danger. Moreover, to reduce the relationship is an easy way to reduce conflicts. All the emperors in Chinese history lay high pressure on commerce, thinking that merchants might make the society unsteady. Chinese were and are so influenced by their culture and tradition that they love their original place very much. Nostalgia is a recurrent theme in Chinese poetry. An American reader of translated Chinese poems may well be taken aback and even put off by the frequency of the lament for home. But that doesn’t mean Chinese never leave their home to establish their career. Home is the softest place in the heart of every Chinese. A Chinese may miss his home, his original place constantly, but be back his birthplace only when he is dying. By contrast, Americans move voluntarily, and their nostalgia for hometown is really longing for a childhood to which they cannot return but not for place they one lived in. In the meantime, Americans believe the future beckons and the future is in open space, not in such steady place. Americans have a sense of space while Chinese has a strong feeling of place. American rootlessness is a result of ideals should be admired, namely, social mobility and optimism about future. Chinese rootedness is a result of loyalty and allegiance. People of different nations should be aware of the differences among them, and make understanding of each other. Let people of different nations unit despite of their differences to build a world of harmony! May 20 红楼杂记在家的那几天,挺累的,没怎么出门,重读红楼梦,有点小小的感慨。
又读红楼
枕边一部石头铭
世上多少红楼梦
痴人无奈悲千古
夜半眼泪对残灯
黛玉
由来多愁多病身,
空负倾城倾国貌。
洒向潇湘泪也冷,
诗成桃李花易凋。
捧心西子三分怨,
倚桂姮娥一点娇。
心断梦残魂偏消,
奈何世上痴情少。
宝钗
碧玉出侯门
婷婷此一身
有才堪咏絮
无情也动人
谁谓停机德
他是禄蠹根
徒倚阑干久
帘钩挂月昏
元春
花月难久好
无常鬼又到
生作芙蓉面
博得君王笑
玉阶凝碧色
宫闱冷衰草
都说爆竹响
转眼已散消
迎春
可怜金艳花玉质
偏来家运不齐时
袅袅有态迎香淡
默默无声春语耻
何事修得狼为君
此生付与流水知
坟上新土谁人添
明年东风念今日
探春
鼓乐声中笑语寒
万里西风一线牵
玉关城外春虽完
探家还比探春难
惜春
秀发结住尘世怨
青丝理断情愁缘
侯门女卧古佛边
寂寞晚鸦满庭院 |
|
|