转行小白成长路-java篇
第五章:初始化与清理(下)
- 垃圾回收这肯定不是简简单单就能讲述明白的,毕竟创造与回收应该是同等重要的,因为内存就那么多嘛。垃圾回收最大的特性就是不确定性,毕竟面临的情况是复杂多样的。比如说超大对象和极小对象处理的方式肯对不会相同,因为这样会极大的拖慢程序的运行速度。总之它进行垃圾回收时一定是多种算法并存的。目的就是为了减少对程序性能的影响。提到垃圾回收目前就知道gc(),设计虚拟机的底层运作方式,书中介绍有两种方式,标记-清扫和标记-复制-清扫。这两种方式结合就也难怪出现不确定性了,程序运行时会运行标记-清扫,及时把小的对象清扫出去,大的标记,等到内存不够了,进行标记-复制-清扫,然后紧凑紧凑对象存储的位置,导致存储空间的释放会影响开辟空间的速度。但是也是有问题的垃圾回收只能识别带有引用的对象,可是像数据库连接,文件IO这种不符合垃圾回收标准的,都是可以使用finalize来手动处理。但要命的是这个finalize我们不知道它什么时候执行,不知道它有没有执行。原因比较好分析,因为我们已经用不到这个对象了才会使用这个方法,结合垃圾回收的特性自然也没办法考证。所以最好的方法就是尽量不要用。如果让我们来想这个功能如何实现,肯定是要在了解ram就是内存存储的区域的特性的基础上才能进行下去,看来欠缺的不是一丁点。耗时长短百度百科上讲与存储内容无关,与访问顺序有关,确切需要以后了解了,但是似乎也能理解标记-复制-清扫的原因了。
- 初始化顺序static最先实现,毕竟它的生命周期同类型一样长,不属于对象,也就在构造器之前被执行,将源码类解析成class文件观察是最优说服力的。static最先执行stack1表示堆栈1,成员变量先声明然后在构造器中赋值,然后是块级赋值,最后执行构造器内容。这应该也证明了,在堆区建立对象的指令应该是构造器传递的。先建立堆栈部分的引用,然后在建立堆中数据,建立关系。
// Compiled from Farther.java (version 1.8 : 52.0, super bit) public class com.zhangwei.hello.quick.reuse.Farther { // Field descriptor #11 I private int age; // Method descriptor #13 ()V // Stack: 2, Locals: 1 public Farther(); 0 aload_0 [this] 1 invokespecial java.lang.Object() [1] 4 aload_0 [this] 5 bipush 12 7 putfield com.zhangwei.hello.quick.reuse.Farther.age : int [2] 10 getstatic java.lang.System.out : java.io.PrintStream [3] 13 ldc <String "This is a block"> [4] 15 invokevirtual java.io.PrintStream.println(java.lang.String) : void [5] 18 getstatic java.lang.System.out : java.io.PrintStream [3] 21 ldc <String "This is a constructor"> [6] 23 invokevirtual java.io.PrintStream.println(java.lang.String) : void [5] 26 return Line numbers: [pc: 0, line: 15] [pc: 4, line: 9] [pc: 10, line: 12] [pc: 18, line: 16] [pc: 26, line: 17] // Method descriptor #13 ()V // Stack: 1, Locals: 1 static {}; 0 ldc <String "name"> [7] 2 astore_0 3 return Line numbers: [pc: 0, line: 6] [pc: 3, line: 7] }