`
styleself
  • 浏览: 1371 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
最近访客 更多访客>>
社区版块
存档分类
最新评论

重新学习Thinking in JAVA散记(学习笔记)

阅读更多
(一)
Class Banana{
  void f(int i){/*...*/};
}

Banana a = new Banana() , b = new Banana();
a.f(1);
b.f(2);

为了能够简便、面向对象的语法来编译代码---即“发送消息给对象”,编译器做了一些幕后的工作。它暗自把“所操作对象的引用”作为第一参数传递给f()。所以上述两个方法调用就变成了这个样子:

Banana.f(a,1);
Banana.f(b,2);


Banana对象里面的this代表对象的引用。

在构造函数的时候,我们可以用this去调用另外一个构造函数,但是不能调用两个或者两个以上,并且调用构造函数必须在最起始处。


(二)垃圾回收器如何工作:

C++里的堆想像成为一个院子,里面每个对象都负责自己的地盘。
JAVA里的堆可以想象为一个传送带,每分配一个新对象,它就往前移动一格。(未必完全像)
    1、引用计数(reference counting)是一种简单但速度很慢的垃圾回收机制,每个对对象都含有一个引用计数器,当有引用连接至对象时,引用计数器加1,当引用离开作用域的时候被置为null时,引用计数器减1。
  缺陷:在程序的周期中继续地开销,全部对象的遍历。对象之间循环引用,可能出现“对象应该被回收,但是引用计数器不为0”的情况。
  从未被用于任何一种JAVA虚拟机上。
  
   2、第二种办法:任何“活”的对象,一定能最终追溯到其存活的堆栈或者静态存储区之中的引用。这个引用链条可能会穿过数个对象层次。。由此,如果你从堆栈和静态存储区开始,遍历所有的引用,就能找到所有“活”的对象,对于发现的每个引用都进行追踪,直到“根源于堆栈和静态存储区的引用”所形成的网络全部被访问为止。
  “停止-复制”(stop-copy):先暂停程序,然后将所有“活”的对象从当前的堆复制到另外一个堆,重新复制之后,复制后的对象是一个个挨着的,所有新堆保持紧凑排列。两个效率低的原因:一是两个对,二是两个堆之间来回倒腾。
   “标志--清扫”(mark-and-sweep),同样从堆栈和静态存储器出发,遍历所有的引用,进而找出所有存活的对象,找到一个标记一个,然后清理没有标记的内存。清理以后内存是不连续的,如果要连续,必须重新整理。
  
    实际的虚拟机中,内存分配单位是较大的“块”,每个块都有相应的“代数”(generation count)的记录它是否还存活,大的独享不会复制,只是代数增加,只有内含的小型对象的块则被复制并整理,虚拟机会进行监视,如果所有都很稳定,垃圾回收器的用“标记--清扫”,如果出现很多碎片,会用“停止-复制”的方式。


(三)程序初始化顺序
 
   找到类的路径-->加载类-->加载静态初始化-->在堆上为类分配空间-->初始化类里面的基本类型数据-->执行所有出现于域定义处的初始化动作-->执行构造器。


class Test{
	
	int i = 1; //second 
	
	static int x;
	static {
		x = 3;
		System.out.println("in static"); //first
	}
	
	public Test(){
		System.out.println("i == "+i);
		System.out.println("in construction");
		i = 3;  //third
		System.out.println("i == "+i);
	}
	
	
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics