zoukankan      html  css  js  c++  java
  • [Java] 一、对象的创建 & 销毁

    *1、考虑静态工厂方法(static factory method)代替构造器?!优势?不足?

    服务提供者架构:

    1、服务接口(Service Interface) -- 提供者实现的;

    2、提供者注册API(Provider Registration API)--系统用于注册实现,让客户端访问它们;

    3、服务访问API(Service Access API)--客户端用于获取服务的实例;[它是“灵活的静态工厂”,构成了服务提供者架构的基础!]

           *4、服务提供者接口(Service Provider Interface)--这些提供者负责创建其服务实现的实例

         [如果没有Service Provider Interface,实现就按照类名称注册,并通过反射方式进行实例化。

    对于JDBC来说,

    Connection就是它的服务接口,

    DriverManager.registerDriver是提供注册API,

    DriverManager.get Connection是服务访问API,

    Driver就是服务提供者接口]

    2、遇到多个构造器参数时要考虑用构造器

    *3、用私有构造器or枚举类型强化Singleton属性

    4、通过私有构造器强化不可实例化的能力

    5、避免创建不必要的对象

    *6、消除过期的对象引用

    // Can you spot the "memory leak"?
    public class stack {
        private Object[] elements;
        private int size = 0;
        private static final int DEFAULT_INITIAL_CAPACITY = 16;
    
        public Stack() {
            elements = new Object[DEFAULT_INITIAL_CAPACITY];
        }
        
        public void push(Object e) {
            ensureCapacity();
            elements[size++] = e;
        }
        
        public Object pop() {
            if (size == 0)
                throw new EmptyStackException();
            return elements[--size];
        }
    
        /**
         * Ensure space for at least one more element, roughly
         * doubling the capacity each time the array needs to grow.
         */
        private void ensureCapacity() {
            if (elements.length == size)
                elements = Arrays.copyOf(elements, 2*size+1);
        }
    }

    BUG:“内存泄漏”,随着垃圾回收器活动的增加,或者由于内存占用的不断增加,程序性能的降低逐渐表现出来。极端情况、

    会导致磁盘交换(Disk Paging),甚至导致程序报错(OutOfMemoryError)--少见!

    eg:如果一个栈先是增长,再收缩,那么从栈中弹出来的对象将不会被当作垃圾回收,即使使用栈的程序不再引用这些对象,它们也

    不会被回收。因为:栈内部维护着对这些对象的过期引用(obsolete reference)--即永远也不会再被解除的引用。本例中,elements

    数组的“活动部分(active portion)”之外的任何引用都是过期的。活动部分指:elements中下标小于size的那些元素。

    fix bug:一旦对象引用过期,需要清空这些引用。即修改pop方法,如下;

        public Object pop() {
            if (size == 0)
                throw new EmptyStackException();
            Object result = elements[--size];
            elements[size] = null; // Eliminate obsolete reference.
            return result;
        }

    好处:

    1、解决BUG出现的内存长期占用,降低性能;

    2、如果它们以后又被错误的解除引用,程序就会抛出NullPointerException异常,而不是悄悄继续运行下去!

    /**

        * 1、只要是自己管理内存,程序员就应该警惕内存泄露问题;

        *

        * 2、缓存;--把对象引用放到缓存中,它就很容易被遗忘掉;

    [修复:只要在缓存之外存在某个项的键的引用,该项就有意义,那么就可以用WeakHashMap代表缓存!

      “缓存项的生命周期是否有意义”--不容易确定。LinkedHashMap类利用它的removeEldestEntry方法!

      更加复杂的缓存,必需直接使用java.lang.ref!]

        *

        * 3、监听器 & 其他回调

    [eg:如果你实现一个API,客户端在这个API中注册回调,却没有显式地取消注册,那么除非你采取某些动作,否则

      它们就会聚集。确保回调立即被当作垃圾回收的最佳方法是只保存它们的弱引用(weak reference),例如,只将它们

    保存成WeakHashMap中的键。]

        *

        **/

    7、避免使用终结方法?(即finalizer)

    “不要把终结方法当作是C++析构器的对应物!(构造器)”

    C++:析构器(destructors)回收一个对象所占用的资源,是构造器所必需的对应物; --也可以回收其他的非内存资源

    Java:当一个对象变得不可到达时,垃圾回收机制会回收与该对象相关联的存储空间;--用try-finally实现类似工作

    ........................................................................

    Effective Java 

      -- Second Edition (James Gosling)

    ........................................................................

  • 相关阅读:
    Java实现 计蒜客 拯救行动
    Java实现 计蒜客 拯救行动
    Java实现 LeetCode 174 地下城游戏
    Java实现 LeetCode 174 地下城游戏
    Java实现 LeetCode 174 地下城游戏
    Java实现 LeetCode 173 二叉搜索树迭代器
    Java实现 LeetCode 173 二叉搜索树迭代器
    Visual Studio的SDK配置
    怎样使用CMenu类
    mfc menu用法一
  • 原文地址:https://www.cnblogs.com/Trybst/p/5498474.html
Copyright © 2011-2022 走看看