关于垃圾回收的几个问题

[color=red]一.为什么要清理 [/color]

为了回收程序不在使用的内存,垃圾回收器会负责释放对象占用的内存,在使用程序库时,把一个对象用完后就“弃之不顾”的做法是不安全的,java作为安全性较高的一种高级语言内置了专门的垃圾回收机制来负责收回无用对象占用的内存资源。

[color=green]要清楚垃圾回收工作方式首先了解下对象在堆和栈存储形式:[/color]

[color=green]堆(Heap):[/color]存储对象实例包含对象的实例的属性值,属性类型和对象本身的类型标记(并 不保存对象的方法)

[color=green]栈(堆栈)(Stack): [/color]存储基本数据类型,指令代码(包过对象方法),常量,对象句柄(对象引用的地址)等。

对象实例在heap中分配好以后,需要在stack中保存一个4字节的heap内存地址,用来定位该对象实例在heap中的位置,便于找到该对象实例。

[color=green]它们的区别:[/color]
Java 的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。"
栈的优势:存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄。 ”
所以说: 垃圾回收System.gc()是针对堆Heap的,而栈因为本身是FILO协议:first in, last out. 先进后出,能够自动释放。 这样就能明白到new创建的,都是放到堆Heap!

[color=red]二.何时清理[/color]

java 的垃圾回收器 是不定时的,也许你会发现,只要内存没有频临存储空间用完那一刻,对象占用的空间就总也得不到释放。如果程序执行结束,并且垃圾回收器一直都没有释放你创建的任何对象的存储空间,当随着程序的退出,那些RAM资源也全部交给了操作系统。 其实这样做是恰当的,因为你要知道垃圾回收本身也要使用内存开销,如果在没必要(内存资源充足)使用它来工作的情况下,又何必多此一举呢?

[color=red]三.finalize()的使用:[/color]

 垃圾回收器只知道释放那些由new 分配的内存,所以它不知道该如何释放该对象的“特殊(即通过new 创建对象以外的方式创建对象分配了内存:比如在使用本地方法的情况下,非java代码中出现的对象如:c++)”内存。为了应对这种情况,java 允许在类中定义一个名为finalize()的方法。它的工作原理是这样的:一旦垃圾回收器准备释放对象占用的存储空间,将在这之前调用该对象finalize(),并在下一次垃圾回收动作发生时,才会真正的回收对象占用的内存。所以要是使用了finalize()就意味着在垃圾回收时刻做了一些垃圾回收器无法回收对象特殊内存的清理。

[color=green]finalize()在以下情况下被调用:[/color]

1.所有对象被Garbage Collection时自动调用,比如运行System.gc()的时候.
2.程序退出时为每个对象调用一次finalize方法。
3.显式的调用finalize方法

除此以外,正常情况下,当某个对象被系统收集为无用信息的时候,finalize()将被自动调用,但是jvm不保证finalize()一定被调用,也就是说,finalize()的调用是不确定的,这也就是为什么sun不提倡使用finalize()的原因.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值