管理与分配内存

作者: looper1211 | 来源:发表于2016-05-24 20:36 被阅读175次

    1. java的内存管理机制


    Java的内存管理就是对象的分配和释放问题 ,分两个部分

    • 分配:内存的分配是由程序完成的,程序员需要通过关键字new 为每个对象申请内存空间 (基本类型除外),所有的对象都在堆 (Heap)中分配空间

    • 释放:对象的释放是由垃圾回收机制决定和执行的,这样做确实简化了程序员的工作。但同时,它也加重了JVM的工作。因为,GC为了能够正确释放对象,GC必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC都需要进行监控

    简单来说,java的自动内存管理有效的消除了软件开发过程中许多常见的问题,开发者不需记住为每一个新建的对象释放内存,但是却要为这个功能付出代价,因为自动的垃圾回收器会和应用程序并行运行,这意味着它会和应用程序竞争CPU时间,此外自动内存管理无法保证不会内存泄漏

    2. 减少对象分配


    在java和Android中,自动内存管理最常见的问题就是分配了无用的对象,导致垃圾回收器一直在运行,看如下代码:

    public class Data {
    
        private int firstData;
        private int secondData;
    
        public Data(int firstData, int secondData) {
            this.firstData = firstData;
            this.secondData = secondData;
        }
        
        public void badObjectAllocationExample(int datas[]){
            if(datas.length%2!=0){
                return;
            }
            for (int i = 0; i < datas.length; i+=2) {
                Data data = new Data(datas[i], datas[i+1]);
                printfData(data);
            }
        }
        
        public void printfData(Data data){
            System.out.println(data.firstData +"-"+ data.secondData);
        }
    }```
    显然在上面的代码中出现了一个很常见的错误:*在循环中分配内存*。在上面的循环中,垃圾回收器将会做很多工作,并佷有可能耗尽CPU从而导致应用程序用户界面卡顿。有一种改进方法如下:
    ```java
        public void set(int firstData, int secondData) {
            this.firstData = firstData;
            this.secondData = secondData;
        }
        
        public void badObjectAllocationExample(int datas[]){
            if(datas.length%2!=0){
                return;
            }
            Data data = new Data(0, 0);
            for (int i = 0; i < datas.length; i+=2) {
                data.set(datas[i], datas[i+1]);
                printfData(data);
            }
        }
    

    这个方法确保了在整个运行过程中一直重用该对象,当对象方法返回时,只会有一次的垃圾回收,但是在开发中有时无法避免在循环中创建对象,所以还需要采用其他方法处理这种情况,于是有了以下的解决方案:

    public  class Data {
    
        public int firstData;
        public int secondData;
        private  Data next;
        private static final Object sPoolSync = new Object();
        private static Data sPool;
        private static int sPoolSize = 0;
        private static final int MAX_POOL_SIZE = 50;
        
        private Data(){}
        
        public static Data obtain(){
            synchronized (sPoolSync) {
                if(sPool!=null){
                    Data m = sPool;
                    sPool = m.next;
                    m.next = null;
                    sPoolSize--;
                    return m;
                }
            }
            return new Data();
        }
        
        public void recycle(){
            synchronized (sPoolSync) {
                if(sPoolSize<MAX_POOL_SIZE){
                    next = sPool;
                    sPool = this;
                    sPoolSize++;
                }
            }
        }
    }
    

    这是使用静态工厂的方法,看起来很熟悉,因为在Android源代码和API的很多地方都用过,比如Message、MotionEvent等都是通过这种模式来减少不必要的垃圾回收。

    相关文章

      网友评论

      本文标题:管理与分配内存

      本文链接:https://www.haomeiwen.com/subject/icwzrttx.html