`
wzucxd
  • 浏览: 26558 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

finalize分析笔记

 
阅读更多

package com.test;

public class Son {

static boolean isgcrun=false;
static boolean flag=false;
static int created=0;
static int finalized=0;
int i;

public Son(){
i=++created;
if(i==100){
System.out.println("i have 100 sons");
}
}

protected void finalize() throws Throwable {
if(!isgcrun){
isgcrun = true;
System.out.println("gc kill sons...start!!!,"+ i + " sons killed ");
}
if(i==100){
System.out.println("-------set flag!!!---don't kill son!!!----");
flag = true;
}
finalized ++ ;
if(finalized >= created){
System.out.println("all killed!!!");
}
}
}

package com.test;

public class Father {

public static void main(String[] args) {
while(!Son.flag){
new Son();
new String("站岗中。。。。");
}

System.out.println( "After all son have been created:/n"+
"total created ="+Son.created+
",total finalized ="+Son.finalized);
System.out.println("gc():");
System.gc();
System.out.println("runFinalization():");
System.runFinalization();
System.out.println("bye");
}
}
运行结果:
i have 100 sons
gc kill sons...start!!!,4544 sons killed
-------set flag!!!---don't kill son!!!----
After all son have been created:
total created =47649,total finalized =30257
gc():
runFinalization():
all killed!!!
bye

分析:
在一个循环当中创建对象,并且只是创建,而不引用,也就是说这个对象会自动的被系统当作垃圾处理掉。
但请注意,finalize()方法并不是立刻就会执行的,执行的时间完全由系统来决定。
所以很有可能的情况是已经创建了20000个对象,才开始其中的某一个对象的清除工作(这可能和时间或者系统内容的占用有关)。
为什么会被自动被系统当作垃圾回收?系统什么时候开始回收?
我们从jvm的gc顺序中可以分析得到答案
A. JVM会试图为相关Java对象在Eden中初始化一块内存区域(所有新对象不断的创建,并放在Eden中,使得Eden不断膨胀)
B. 当Eden空间足够时,内存申请结束。否则到下一步(对象太多,内存资源开始不足)
C. JVM试图释放在Eden中所有不活跃的对象(没有任何引用的对象为不活跃对象,判断原则;系统将会决定在这个时候回收掉这个对象)

引:不活跃对象判断原则(http://hi.baidu.com/jieriw/blog/item/6f690f32f793e6cda3cc2bd5.html)
应用阶段:即该对象至少有一个引用在维护他.
不可视阶段:即超出该变量的作用域。这里有一个很好的做法,因为JVM在GC的时候并不是马上进行回收,而是要判断对象是否被其他引用在维护.所以,这个时候如果我们在使用完一个对象以后对其obj=null或者obj.doSomething()操作,将其标记为空,可以帮助JVM及时发现这个垃圾对象.
不可到达阶段:就是在JVM中找不到对该对象的直接或者间接的引用。
可收集阶段,终结阶段,释放阶段:此为回收器发现该对象不可到达,finalize方法已经被执行,或者对象空间已被重用的时候。

我们从这可以发现垃圾回收过程往往都会迟一点才开始,如果有足够的时间gc还是能把这些没用的对象都回收了(让线程wait一会就能看到了),这也是为啥我们都选择在finally中进行文件流之类的关闭操作,因为finalize可靠了,母猪都会爬树了(当然现在母猪也有可能会爬树了);

另外对于finalize的不可靠,Java 1.1 通过提供一个Runtime.runFinalizersOnExit()方法部分地解决了这个问题(现在使用Runtime.exit())。Runtime.exit() 方法并不立即试图启动垃圾回收器。而是当应用程序退出时,它调用每个对象的finalize()方法。

正如你可能猜测的那样,通过调用Runtime.exit()方法强制垃圾回收器清除所有独立对象的内存,当清除代码执行时也可能引起明显的延迟。

文章出处:http://www.dxmath.com/

分享到:
评论

相关推荐

    JAVA程序员面试宝典笔记总结(刘磊版)

    ### JAVA程序员面试宝典笔记总结 #### 1. JDK与JRE - **JDK (Java Development Kit)**:这是Java开发工具包,包含了Java运行所需的各类库和工具,包括编译器、文档、示例代码等。JDK还包含了一个JRE(Java Runtime...

    net学习笔记及其他代码应用

    29.根据线程安全的相关知识,分析以下代码,当调用test方法时i>10时是否会引起死锁?并简要说明理由。 public void test(int i) { lock(this) { if (i>10) { i--; test(i); } } } 答:不会发生死锁,(但...

    ios学习笔记 --sqllite3

    这篇“iOS学习笔记 --SQLite3”旨在帮助新手掌握如何在iOS应用中使用SQLite3进行数据管理,包括创建数据库、插入数据、查询数据等基本操作。 首先,我们需要了解SQLite3的基本概念。SQLite3是一个嵌入式的关系型...

    深入理解Java虚拟机笔记(带目录).docx

    深入理解 Java 虚拟机笔记 Java 虚拟机(JVM)是 Java 语言的运行环境,它负责解释和执行 Java 字节码。下面是 Java 虚拟机相关的知识点: 虚拟机内存结构 Java 虚拟机的内存结构主要包括以下几个部分: * 方法...

    java基础学习笔记(易错点,易混点).doc

    9. **代码块的执行时机**:静态代码块在类加载时执行,实例代码块在对象创建且构造方法执行前执行,`finalize()`方法在对象被垃圾回收器回收前调用。 10. **变量存储位置**:静态变量存储在方法区,实例变量存储在...

    greenplum学习笔记

    REDUCE阶段的实现相对复杂,需要定义TRANSITION函数来处理多次输入记录的合并,以及FINALIZE函数来生成最终结果。此外,还可以选择性地使用CONSOLIDATE函数将多个中间状态合并为一,进一步优化处理流程。 总之,...

    MongoDB学习笔记之分组(group)使用示例

    最后,如果您对MongoDB有更多的兴趣,可以参考相关学习笔记,包括MongoDB的配置、索引使用、文件存取、环境搭建以及各种操作方法,这些都会帮助您更好地掌握MongoDB的使用技巧。无论是在Windows还是Linux环境下,从...

    dotnet 代码优化 聊聊逻辑圈复杂度.rar

    首先,我们来谈谈WPF(Windows Presentation Foundation)源代码笔记。WPF是.NET框架的一部分,用于构建丰富的桌面应用程序。优化WPF代码意味着要关注UI更新的性能、数据绑定的效率以及资源管理。例如,避免在UI线程...

    java垃圾回收器代码举例

    - 使用`finalize()`方法可以让对象在被垃圾回收前有机会执行清理操作,但这个方法的使用应谨慎,因为它可能会干扰垃圾回收过程。 5. **个人笔记** - 调优垃圾回收器涉及多个参数,例如新生代和老年代的比例(`-XX...

    最新的iphone sqlite小程序

    例如,一个阅读应用可以使用SQLite存储用户的阅读历史,一个笔记应用可以存储用户的笔记内容。 通过学习和实践"最新的iPhone SQLite小程序",开发者不仅可以掌握如何在iOS应用中使用SQLite,还能了解到如何有效地...

    sqljs是SQLite数据库的一个JavaScript移植

    例如,它可以用于构建离线版的笔记应用、数据分析工具,或是需要在本地存储用户数据的游戏等。 在实际应用中,使用sql.js的步骤大致如下: 1. 引入库:首先,你需要在HTML文件中引入sql.js的库文件,这通常是一个`...

    Java常见面试题解答.pdf

    2. **final、finally和finalize的区别**:final用于声明一个不可变的字段或类,finally是try-catch语句中用于确保一定会执行的代码块,finalize是Object类的一个方法,用于对象的清理工作。 3. **异常类的区别**:...

Global site tag (gtag.js) - Google Analytics