java 编程感悟二---java对象及内存的回收

作者:和伟

  1. QQ:46219905

转贴请注名作者和出处 

 

java对象及内存的回收

 提到java,很多人会将其同C++进行比较,其中一点最明显的莫过于以下几点:
  java的垃圾回收GC(Garbage Collection )创建
  取消类的多层继承
  指针的取消

在这里,我们主要看下前两点(BTW:类的继承我会在下次有空时提到^_^)
 
 1、GC
  在C++中,内存的回收是由开发者自己来回收,而在java中,java的创始者提出了GC这一概念并将其应用到了JVM中,即开发中申请了内存后由
  JVM 的GC来负责内存的回收
  一种对于一般开发者的困惑就是对象和内存的混淆,接下来我们来看下这两者的区别
  我们认为java同C++一样,是属于面向对象的语言,Bruce在 Thinking in Java 书中提到,在java中,一切皆为对象,这句话我认为应这样理解,其包括以下两层含义:
  1>java中一切等均为继承Object而来
  2>java中包括内存的分配等均使用对象来完成
  
  在java中,我们不用直接来进行内存等的操作,这一切均是通过对象的创建和销毁来完成的,例
  
  Object object = new Object();
  object.do();
  
   另外一个好处是,对象的完成后,JVM GC 会帮我们自己来进行对象的摧毁(Destory)来达到内存的释放

  但是,注意到这里边有个问题,在阐明这个问题之前,我们首先来看下java JVM中的内存管理,进而理解和发现这个问题的焦点.

  我们知道,java是移植性高的一种面向对象语言,如Sun所说,"一次编写、到处运行"的概念,基于目前操作系统等核心的不同,Sun
   创建了JVM这样一种容器(我们暂且称为容器吧),用来运行java语言,这样无论在哪种操作系统上,java始终是运行在自己的JVM容器上,
  运行的机制是由jvm来完成的,所以,这样一来跨平台、移植性的问题就解决了.

   在JVM中,内存的一般体现在静态申请(Static)、堆(Heap)和栈(Stack)三者上,我们主要来看下后两者
   内存的管理通常是由Heap和Stack来完成的,Heap是用来存放对象的实际内容,Stack则是用来存放对象的地址链接的,即我们通常所
   说的对象引用
   通常我们通过对象的申请new来实现的对象内容实际是存储在Heap中的,而我们对对象的引用是在Stack上进行的,看以下例子你会更明白些
   Object object = new Object(); //对象的内容是存储在Heap中的,而对于对象的引用是在Stack上来完成的
   ...
  
   对象在完成之后,通常GC会根据实际情况,将Stack中不再引用的对象从Heap 中收回

   当需要内存申请时,JVM会通过从Heap中分配内存,并将引用保存在Stack中,当JVM发现Heap 中设置的内存不够时,会通过GC来回收,
   而当GC发现Heap中内存不够时,并且无法再分配更多内存时,就会出现了常见的内存溢出(Memory leak),随之扔出OutMemory异常.
   
    顺便提一下,目前的JVM有几种版本,但对于GC的回收无外乎通过对象的可到达或对象的累计增减来完成回收,大多数JVM采用前者来实现GC
    的回收操作.

  问题的焦点终于出现了,当GC发现对象引用不可到达时,可以及时进行内存的回收,但在有些时候,GC却无法实现对象的摧毁,请看以下

   ObjectA a = new ObjectA();
    ObjectB b = new ObjectB();
    ObjectC c = new ObjectC();
  
    //a 引用了b对象
   //b引用了c
    //a对象结束

   这时候GC发现a引用不可到达,a对象引用随之被摧毁,但这时GC却发现b和c对象引用是可到达的,所以暂只能对a对象进行内存的回收.
    ... //程序经过多次反复运行后

   OutMemory Error问题发生了!  //很遗憾,谁都不喜欢看到这种现象(当然也包括我^_^),但是它毕竟还是出现了。
  
   反之按照如下进行规范操作,就会避免这种现象的发生
   Object a = new Object();
    a.do();
    a = null; //解除引用
   虽然JVM有时候会帮我们完成这一步,但它毕竟不是那么万能,所以我们不能太过于依赖GC  
   
   综上所述,限于目前算法的有限性,JVM GC并非万能,有些情况下也无法对对象进行摧毁和内存的回收,我们不可过多依赖于
   JVM GC的回收机制,所以在实际的程序编写中,如果一个对象完成时,我们尽量解除相关的对象引用,从而达到内存的释放,这时候既
   排除了Memory leak的隐患,也减少了GC频繁运作,提高了JVM的运行效率,又何乐而不为呢?  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值