首页 > 编程语言 > 详细

4,java内存回收

时间:2015-10-14 12:43:51      阅读:285      评论:0      收藏:0      [点我收藏+]

1,jvm在何时决定回收一个java 对象所占据的内存:?

2,jvm会不会漏掉回收某些java对象,使其造成内存泄漏?

3,jvm回收java对象得实现细节。?

4,jvm能否对不同java对象占用的内存区分对待,回收?

 

1,判断一个对象是否可回收得标准就是在于该对象是否被引用。

2,java对象得引用分为如下几种;

        强引用,   软引用     弱引用和  虚引用

       jvm的垃圾回收机制采用有向图的方式来管理内存中的对象。当一个对象不可到达的时候就可以把它回收。

        对象的三种状态,可到达 可恢复  不可达

         强引用:这是java最常见得引用方式,程序创建一个对象,并且把一个对象赋给一个引用变量,这个引用变量就是强引用。被强引用所引用的对象绝对不会被垃圾回收机制回收,即使系统内存非常紧张。因此强引用是造成java内存泄漏得主要原因之一。

        软引用:软引用需要通过SoftReference类来实现。当一个对象只具有软引用的时候,它就有可能被垃圾回收机制回收,对于只有软引用的对象而言,当系统内存控件足够时,它不会被系统回收,当不够时,就会被回收。当系统内存空间足够时,强引用和软引用没有太大得区别。

        弱引用:弱引用和软引用类似,但是弱引用的生存周期更短。当系统垃圾回收机制运行时,不管系统内存是否足够,总会回收该对象所占用的内存。

 

如果存在没有用,但是有没有回收得内存,那就是内存泄漏;例如arrayList中移除一个元素,必须将这个元素释放。  element[--size]=null  

 

3,内存回收机制主要完成两件事情。

        1,跟踪并且监控每一个java对象,当某一个对象处于不可到达得状态时,回收该对象所占用的内存,2,清理内存分配,回收过程中产生得内存碎片。

        2,垃圾回收得基本算法,压缩,复制,等等。。

             根据对象生存时间的长短,把堆内存分为3代;

            young,old。permanent。不同代得特点采用不同得回收算法。

        堆内存得分代回收:

                分代回收得一个依据就是对象生存时间的长短,然后采用不同的垃圾回收策略; 这些策略基于一下事实。

                绝大多数的对象是不会被长时间引用,这些对象在其young期间就会被回收

                很老的对象和很新得对象之间很少存在相互引用。

                对于young代,采用复制算法只需遍历那些处于可达状态得算法。而且这些对象数量少,复制成本不大。

                对于old代,空间相对较大,没那么容易死,而且对象多,所以对于old对象,回收的频率不用太高,因此很少对象会死掉。每次对old代码执行垃圾回收需要更长的时间来完成。

               所以它一般采用标记压缩算法。

                对于permanent代,主要用于装在class,方法等信息,默认时64M。垃圾回收机制通常不会回收permanent代中的对象,对于那些需要加载很多类的服务器程序,旺旺需要加大permanent代内存,否则可能因为内存不足而导致程序终止。

        当young内存快要用完的时候,垃圾回收机制会对young代进行垃圾回收,垃圾回收机制会采用较高得频率对young代进行扫描和回收,因此这种回收得开销比较小,因此被称为次要回收(minor collection)当old代的内存块要用完的时候,垃圾回收机制会进行全回收,也就是对young和old都要进行回收,这样的回收成本就大的多,因此,也称之为主要回收(major collection)。

常见的垃圾回收器:串行回收器,并行回收器,并行压缩回收器···等等

 

内存管理上的小技巧:

        1,尽量使用直接量,不要用new的方式来创建,而是直接使用直接量

         例如:用String str="hello"  而非String str=new String("hello")

 

        2,使用StringBuilder和StringBuffer进行字符串连接。

        3,尽早释放无用对象的引用。

   public void info(){
                    Object obj=new Object();
                    sysout(obj.toStirng());
                    obj=null;
                    }

 

            上面的obj=null是没有必要的,因为obj引用对象得作用域结束,原来的obj就会变成垃圾。

    public void info(){
                    Object obj=new Object();
                    sysout(obj.toStirng());
                    obj=null;
                    //需要执行耗时,耗内存操作
                    }

 

                此时obj=null时有必要的,尽早得释放对Object的引用。在执行耗时操作的时候,Obj对象可能被垃圾回收。

            4,尽量少使用静态变量:

        class Person{
            static Object obj=new Object();
                    }

 

            垃圾回收机制通常不会回收这个对象所占用的内存的。对于Object而言,只要obj变量还引用它,他就不会被垃圾回收机制所回收。obj变量时Person类的静态变量,因此它的生命周期与person类同步在person类不被卸载得情况下,Person类对应的Class对象会常驻内存。知道程序运行结束,所以obj所引用的object对象一旦被创建。也会常驻内存,知道程序运行结束。

        5,避免在京藏调用的方法,循环中创建java对象

        例如:

        public static void main(String[] args)
            {
                for(int i=0;i<10;i++){
                                    Object obj=new Object();
                                /   /执行其它操作
                                }
            }

 

                循环导致Object会被创建10次,因此系统需要为这十个对象分配内存控件,执行初始化操作,这是个对象的生存周期不长,接下来系统又需要不断的回收他们说占的内存空间,这种不断的分配,回收操作中程序得性能会受到很大的影响。

            6,缓存经常使用得对象

        实现缓存的两种方式:1,使用HashMap进行缓存。2,直接使用某些开源缓存项目;(例OSCache,他们大都实现了FIFO,MRU等算法,按照算法来淘汰容器中不需要得缓存对象)   缓存本身就是一种以空间换时间的技术;

            缓存设计的关键:如何控制该容占用的内存不至于过大,而该容器又能保留大部分已用过的对象;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4,java内存回收

原文:http://my.oschina.net/u/2480757/blog/517006

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!