Java 垃圾回收器学习

编程入门 行业动态 更新时间:2024-10-25 02:21:26

Java <a href=https://www.elefans.com/category/jswz/34/1770876.html style=垃圾回收器学习"/>

Java 垃圾回收器学习

一 

引言:最近在看《Thinking in java》,不得不说号称java四大名著的书籍,的确有俩把刷子,解决了很多我以前不理解的问题。楼主是一个菜鸟,写这篇博客供以后学习,参考,若有不对的地方,请各位大牛指出。

先看一段代码:
<span style="font-family:Microsoft YaHei;font-size:14px;">public void test(int i)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>book b=new book();
<span style="white-space:pre">	</span>}</span>

大家先来看看这个方法,它是主类里面的一个方法,book类是我自定义的一个类。我先抛出一个问题问下大家。主类每次调用test()方法,book对象会被反复的创建吗?? 再次之前楼主这样理解的:book对象会被反复的创建但是当b的作用域结束时对象book(),就会被清除内存。 事实究竟是这样的吗?  书上给出的解释:“ 当引用b在作用域终点就会消失。然而b指向的对象book依旧存在内存中 ”。但是因为垃圾回收器的存在。在内存中的book对象肯定不会很多,不会创建一个book,内存中就开辟了一片内存。
接下来我来介绍俩个方法这俩个方法是所有的类都具有的:finalize()和System.gc() finalize()方法的作用:我根据书本的意思理解为:标记。垃圾回收器在内存不够的情况下才会回收垃圾,垃圾回收器假如当前正在回收A垃圾,当回收完了在回收B垃圾。垃圾回收器肯定不会说在回收完A之后,然后再根据一系列算法决定回收B,肯定在回收A垃圾过程中或者开始之前就已经知道下一个回收B。
所以我对finalize() 方法的理解就是标记,当某一个类调用了finalize()方法后,回收器并不马上就来回收。 书上这样解释的:垃圾回收器在准备回收A对象内存前,将先调用其finalize(),当回收动作发生的时候才会真正回收内存。
System.gc(),根据网上百度的结果:就是让回收器来回收内存。就像现实生活中 你喊人家吃饭,人家肯能说马上就来马上就来,但具体什么时候来却不知道,唯一知道的是 他很快就来。System.gc(),方法类似一个督促的作用。通过这个小例子我想说明的是:System.gc()方法执行了后,回收器并不一定马上来执行。
接下来看一个例子:
<pre name="code" class="java"><span style="font-family:Microsoft YaHei;font-size:14px;">public class book {public void start(){System.out.println("程序开始执行");}public void end(){System.out.println("程序执行结束");}@Overrideprotected void finalize() throws Throwable {end();super.finalize();}</span>
<span style="font-family:Microsoft YaHei;font-size:14px;">}</span>
 
这是book 类。
<span style="font-family:Microsoft YaHei;font-size:14px;">public class Main {public static void main(String args[]){Main main=new Main();book b=new book();b.start();System.gc();}</span>
运行结果:


可以看到 没有打印出 "程序执行结束"的标记。
既然执行了System.gc 为什么半天都没执行finalize()方法呢。没执行finilize()方法 说明当前的book没有被回收。 不难看出  垃圾回收器 会主动回收 引用为null 的对象。 在这里我要提一个观点:引用存放在 堆栈中,一切对象(new 生成的)都存在堆中。(堆和堆栈是java 数据存储的位置,不懂的可以百度看下)。 当引用为空的时候,引用对应的那个对象就会被Gc回收,当然确切时间肯定不清楚。

下面我们将上面的代码稍微改下:
<pre name="code" class="java"><span style="font-family:Microsoft YaHei;font-size:14px;">public static void main(String args[]){Main main=new Main();book b=new book();b.start();b=null;//<span style="background-color: rgb(255, 255, 102);">注意此时引用b为空了</span>System.gc();}</span>
  
运行结果如下:

这时候  “程序运行结束”,说明执行了 finalize()方法,但是具体什么时候回收了这个对象呢。这个不清楚。

上述的demo:主要是讲了一下 回收器的基础知识,下面我们回到文章开头,test方法被多次调用book 对象是否存在多个,或者说book是否new了多个。看下面代码
<pre name="code" class="java"><span style="font-family:Microsoft YaHei;font-size:14px;">public class Main {public static void main(String args[]){Main main=new Main();for(int i=0;i<5;i++){main.test();}}public void test(){book b=new book();b.start();System.gc();}</span>
<span style="font-family:Microsoft YaHei;font-size:14px;">}</span>
 大家看下运行结果: 
 
 

可以看到 有4个输入“程序结束”  5个输出“程序开始” ,这个结果说明俩个问题:
1.System.gc执行完毕 回收器可能不是立刻执行。 2.反复的执行test方法,book对象会被反复创建,但是 当引用b在作用域的终点时,回收器就会来回收垃圾,最终结果 只有一个对象存在于内存中。(当然假如这里你把所有的 引用都保存在list集合中,我猜测 "程序执行结束" 一个都不会运行)
在这里提下:引用b=null  和引用b的作用域消失 不是一个意思。在上述代码b.start 后面加一个b=null  看下,“程序运行结束”会执行几次,经楼主测试  执行了5次这说明 引用作用域消失和引用为null,Gc执行的机制不同。
博客到这里也就结束了。这些内容也是我看书,然后动手写demo来验证,并不是一定正确,这只是代表我的看法,有不同意见大可以提出。花了2,3个小时写这个博客,希望能帮到一些人。楼主本身是一个菜鸟,但是我有一颗不断进取的心,我坚信总有一天会成为专家。借鸿洋大神的一句话:“生命不息,永垂不止”。










更多推荐

Java 垃圾回收器学习

本文发布于:2024-03-10 02:56:36,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1726835.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:垃圾   Java

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!