当前位置: 首页 > news >正文

百度收录较好的网站wix做网站的建议

百度收录较好的网站,wix做网站的建议,查找域名,汕头网页搭建见#xff1a;http://zhangjunhd.blog.51cto.com/113473/53092 maven/Java/web/bootstrap/dataTable/app开发QQ群#xff1a;566862629。希望更多人一起帮助我学习。 1#xff0e;对象的强、软、弱和虚引用在JDK 1.2以前的版本中#xff0c;若一个对象不被任何变量引用http://zhangjunhd.blog.51cto.com/113473/53092 maven/Java/web/bootstrap/dataTable/app开发QQ群566862629。希望更多人一起帮助我学习。 1对象的强、软、弱和虚引用在JDK 1.2以前的版本中若一个对象不被任何变量引用那么程序就无法再使用这个对象。也就是说只有对象处于可触及reachable状态程序才能使用它。从JDK 1.2版本开始把对象的引用分为4种级别从而使程序能更加灵活地控制对象的生命周期。这4种级别由高到低依次为强引用、软引用、弱引用和虚引用。图1为对象应用类层次。图1⑴强引用StrongReference强引用是使用最普遍的引用。如果一个对象具有强引用那垃圾回收器绝不会回收它。当内存空间不足Java虚拟机宁愿抛出OutOfMemoryError错误使程序异常终止也不会靠随意回收具有强引用的对象来解决内存不足的问题。⑵软引用SoftReference如果一个对象只具有软引用则内存空间足够垃圾回收器就不会回收它如果内存空间不足了就会回收这些对象的内存。只要垃圾回收器没有回收它该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存下文给出示例。软引用可以和一个引用队列ReferenceQueue联合使用如果软引用所引用的对象被垃圾回收器回收Java虚拟机就会把这个软引用加入到与之关联的引用队列中。⑶弱引用WeakReference弱引用与软引用的区别在于只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中一旦发现了只具有弱引用的对象不管当前内存空间足够与否都会回收它的内存。不过由于垃圾回收器是一个优先级很低的线程因此不一定会很快发现那些只具有弱引用的对象。弱引用可以和一个引用队列ReferenceQueue联合使用如果弱引用所引用的对象被垃圾回收Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。⑷虚引用PhantomReference“虚引用”顾名思义就是形同虚设与其他几种引用都不同虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用那么它就和没有任何引用一样在任何时候都可能被垃圾回收器回收。虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用与软引用和弱引用的一个区别在于虚引用必须和引用队列ReferenceQueue联合使用。当垃圾回收器准备回收一个对象时如果发现它还有虚引用就会在回收对象的内存之前把这个虚引用加入到与之 关联的引用队列中。ReferenceQueue queue  new ReferenceQueue (); PhantomReference pr  new PhantomReference (object, queue); 程序可以通过判断引用队列中是否已经加入了虚引用来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列那么就可以在所引用的对象的内存被回收之前采取必要的行动。2对象可及性的判断在很多时候一个对象并不是从根集直接引用的而是一个对象被其他对象引用甚至同时被几个对象所引用从而构成一个以根集为顶的树形结构。如图2所示在这个树形的引用链中箭头的方向代表了引用的方向所指向的对象是被引用对象。由图可以看出从根集到一个对象可以由很多条路径。比如到达对象5的路径就有①-⑤③-⑦两条路径。由此带来了一个问题那就是某个对象的可及性如何判断:◆单条引用路径可及性判断:在这条路径中最弱的一个引用决定对象的可及性。◆多条引用路径可及性判断:几条路径中最强的一条的引用决定对象的可及性。比如我们假设图2中引用①和③为强引用⑤为软引用⑦为弱引用对于对象5按照这两个判断原则路径①-⑤取最弱的引用⑤因此该路径对对象5的引用为软引用。同样③-⑦为弱引用。在这两条路径之间取最强的引用于是对象5是一个软可及对象。3使用软引用构建敏感数据的缓存3.1 为什么需要使用软引用首先我们看一个雇员信息查询系统的实例。我们将使用一个Java语言实现的雇员信息查询系统查询存储在磁盘文件或者数据库中的雇员人事档案信息。作为一个用户我们完全有可能需要回头去查看几分钟甚至几秒钟前查看过的雇员档案信息(同样我们在浏览WEB页面的时候也经常会使用“后退”按钮)。这时我们通常会有两种程序实现方式:一种是把过去查看过的雇员信息保存在内存中每一个存储了雇员档案信息的Java对象的生命周期贯穿整个应用程序始终;另一种是当用户开始查看其他雇员的档案信息的时候把存储了当前所查看的雇员档案信息的Java对象结束引用使得垃圾收集线程可以回收其所占用的内存空间当用户再次需要浏览该雇员的档案信息的时候重新构建该雇员的信息。很显然第一种实现方法将造成大量的内存浪费而第二种实现的缺陷在于即使垃圾收集线程还没有进行垃圾收集包含雇员档案信息的对象仍然完好地保存在内存中应用程序也要重新构建一个对象。我们知道访问磁盘文件、访问网络资源、查询数据库等操作都是影响应用程序执行性能的重要因素如果能重新获取那些尚未被回收的Java对象的引用必将减少不必要的访问大大提高程序的运行速度。3.2 如果使用软引用SoftReference的特点是它的一个实例保存对一个Java对象的软引用该软引用的存在不妨碍垃圾收集线程对该Java对象的回收。也就是说一旦SoftReference保存了对一个Java对象的软引用后在垃圾线程对这个Java对象回收前SoftReference类所提供的get()方法返回Java对象的强引用。另外一旦垃圾线程回收该Java对象之后get()方法将返回null。看下面代码:MyObject aRef  new  MyObject(); SoftReference aSoftRefnew SoftReference(aRef); 此时对于这个MyObject对象有两个引用路径一个是来自SoftReference对象的软引用一个来自变量aReference的强引用所以这个MyObject对象是强可及对象。随即我们可以结束aReference对这个MyObject实例的强引用:aRef  null; 此后这个MyObject对象成为了软可及对象。如果垃圾收集线程进行内存垃圾收集并不会因为有一个SoftReference对该对象的引用而始终保留该对象。Java虚拟机的垃圾收集线程对软可及对象和其他一般Java对象进行了区别对待:软可及对象的清理是由垃圾收集线程根据其特定算法按照内存需求决定的。也就是说垃圾收集线程会在虚拟机抛出OutOfMemoryError之前回收软可及对象而且虚拟机会尽可能优先回收长时间闲置不用的软可及对象对那些刚刚构建的或刚刚使用过的“新”软可反对象会被虚拟机尽可能保留。在回收这些对象之前我们可以通过:MyObject anotherRef(MyObject)aSoftRef.get(); 重新获得对该实例的强引用。而回收之后调用get()方法就只能得到null了。3.3 使用ReferenceQueue清除失去了软引用对象的SoftReference作为一个Java对象SoftReference对象除了具有保存软引用的特殊性之外也具有Java对象的一般性。所以当软可及对象被回收之后虽然这个SoftReference对象的get()方法返回null,但这个SoftReference对象已经不再具有存在的价值需要一个适当的清除机制避免大量SoftReference对象带来的内存泄漏。在java.lang.ref包里还提供了ReferenceQueue。如果在创建SoftReference对象的时候使用了一个ReferenceQueue对象作为参数提供给SoftReference的构造方法如:ReferenceQueue queue  new  ReferenceQueue(); SoftReference  refnew  SoftReference(aMyObject, queue); 那么当这个SoftReference所软引用的aMyOhject被垃圾收集器回收的同时ref所强引用的SoftReference对象被列入ReferenceQueue。也就是说ReferenceQueue中保存的对象是Reference对象而且是已经失去了它所软引用的对象的Reference对象。另外从ReferenceQueue这个名字也可以看出它是一个队列当我们调用它的poll()方法的时候如果这个队列中不是空队列那么将返回队列前面的那个Reference对象。在任何时候我们都可以调用ReferenceQueue的poll()方法来检查是否有它所关心的非强可及对象被回收。如果队列为空将返回一个null,否则该方法返回队列中前面的一个Reference对象。利用这个方法我们可以检查哪个SoftReference所软引用的对象已经被回收。于是我们可以把这些失去所软引用的对象的SoftReference对象清除掉。常用的方式为:SoftReference ref  null; while ((ref (EmployeeRef) q.poll()) ! null) {     // 清除ref } 理解了ReferenceQueue的工作机制之后我们就可以开始构造一个Java对象的高速缓存器了。3.4通过软可及对象重获方法实现Java对象的高速缓存利用Java2平台垃圾收集机制的特性以及前述的垃圾对象重获方法我们通过一个雇员信息查询系统的小例子来说明如何构建一种高速缓存器来避免重复构建同一个对象带来的性能损失。我们将一个雇员的档案信息定义为一个Employee类:public class Employee {     private String id;// 雇员的标识号码     private String name;// 雇员姓名     private String department;// 该雇员所在部门     private String Phone;// 该雇员联系电话     private int salary;// 该雇员薪资     private String origin;// 该雇员信息的来源       // 构造方法     public Employee(String id) {        this.id  id;        getDataFromlnfoCenter();     }       // 到数据库中取得雇员信息     private void getDataFromlnfoCenter() {        // 和数据库建立连接井查询该雇员的信息将查询结果赋值        // 给namedepartmentplonesalary等变量        // 同时将origin赋值为From DataBase     } …… 这个Employee类的构造方法中我们可以预见如果每次需要查询一个雇员的信息。哪怕是几秒中之前刚刚查询过的都要重新构建一个实例这是需要消耗很多时间的。下面是一个对Employee对象进行缓存的缓存器的定义:import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.util.Hashtable; public class EmployeeCache {     static private EmployeeCache cache;// 一个Cache实例     private HashtableString,EmployeeRef employeeRefs;// 用于Chche内容的存储     private ReferenceQueueEmployee q;// 垃圾Reference的队列       // 继承SoftReference使得每一个实例都具有可识别的标识。     // 并且该标识与其在HashMap内的key相同。     private class EmployeeRef extends SoftReferenceEmployee {        private String _key  ;          public EmployeeRef(Employee em, ReferenceQueueEmployee q) {            super(em, q);            _key  em.getID();        }     }       // 构建一个缓存器实例     private EmployeeCache() {        employeeRefs  new HashtableString,EmployeeRef();        q  new ReferenceQueueEmployee();     }       // 取得缓存器实例     public static EmployeeCache getInstance() {        if (cache  null) {            cache  new EmployeeCache();        }        return cache;     }       // 以软引用的方式对一个Employee对象的实例进行引用并保存该引用     private void cacheEmployee(Employee em) {        cleanCache();// 清除垃圾引用        EmployeeRef ref  new EmployeeRef(em, q);        employeeRefs.put(em.getID(), ref);     }       // 依据所指定的ID号重新获取相应Employee对象的实例     public Employee getEmployee(String ID) {        Employee em  null;        // 缓存中是否有该Employee实例的软引用如果有从软引用中取得。        if (employeeRefs.containsKey(ID)) {            EmployeeRef ref (EmployeeRef) employeeRefs.get(ID);            em (Employee) ref.get();        }        // 如果没有软引用或者从软引用中得到的实例是null重新构建一个实例        // 并保存对这个新建实例的软引用        if (em  null) {            em  new Employee(ID);            System.out.println(Retrieve From EmployeeInfoCenter. ID  ID);            this.cacheEmployee(em);        }        return em;     }       // 清除那些所软引用的Employee对象已经被回收的EmployeeRef对象     private void cleanCache() {        EmployeeRef ref  null;        while ((ref (EmployeeRef) q.poll()) ! null) {            employeeRefs.remove(ref._key);        }     }       // 清除Cache内的全部内容     public void clearCache() {        cleanCache();        employeeRefs.clear();        System.gc();        System.runFinalization();     } } 4使用弱引用构建非敏感数据的缓存4.1全局 Map 造成的内存泄漏无意识对象保留最常见的原因是使用Map将元数据与临时对象transient object相关联。假定一个对象具有中等生命周期比分配它的那个方法调用的生命周期长但是比应用程序的生命周期短如客户机的套接字连接。需要将一些元数据与这个套接字关联如生成连接的用户的标识。在创建Socket时是不知道这些信息的并且不能将数据添加到Socket对象上因为不能控制 Socket 类或者它的子类。这时典型的方法就是在一个全局 Map 中存储这些信息如下面的 SocketManager 类所示使用一个全局 Map 将元数据关联到一个对象。public class SocketManager {     private MapSocket, User m  new HashMapSocket, User();       public void setUser(Socket s, User u) {        m.put(s, u);     }       public User getUser(Socket s) {        return m.get(s);     }       public void removeUser(Socket s) {        m.remove(s);     } } 这种方法的问题是元数据的生命周期需要与套接字的生命周期挂钩但是除非准确地知道什么时候程序不再需要这个套接字并记住从 Map 中删除相应的映射否则Socket 和 User 对象将会永远留在 Map 中远远超过响应了请求和关闭套接字的时间。这会阻止 Socket 和 User 对象被垃圾收集即使应用程序不会再使用它们。这些对象留下来不受控制很容易造成程序在长时间运行后内存爆满。除了最简单的情况在几乎所有情况下找出什么时候 Socket 不再被程序使用是一件很烦人和容易出错的任务需要人工对内存进行管理。4.2如何使用WeakHashMap在Java集合中有一种特殊的Map类型—WeakHashMap在这种Map中存放了键对象的弱引用当一个键对象被垃圾回收器回收时那么相应的值对象的引用会从Map中删除。WeakHashMap能够节约存储空间可用来缓存那些非必须存在的数据。关于Map接口的一般用法。下面示例中MapCache类的main()方法创建了一个WeakHashMap对象它存放了一组Key对象的弱引用此外main()方法还创建了一个数组对象它存放了部分Key对象的强引用。import java.util.WeakHashMap;   class Element {     private String ident;       public Element(String id) {        ident  id;     }       public String toString() {        return ident;     }       public int hashCode() {        return ident.hashCode();     }       public boolean equals(Object obj) {        return obj instanceof Element  ident.equals(((Element) obj).ident);     }         protected void finalize(){        System.out.println(Finalizing getClass().getSimpleName() ident);     } }   class Key extends Element{     public Key(String id){        super(id);     } }   class Value extends Element{     public Value (String id){        super(id);     } }   public class CanonicalMapping {     public static void main(String[] args){        int size1000;        Key[] keysnew Key[size];        WeakHashMapKey,Value mapnew WeakHashMapKey,Value();        for(int i0;isize;i){            Key knew Key(Integer.toString(i));            Value vnew Value(Integer.toString(i));            if(i%30)               keys[i]k;            map.put(k, v);        }        System.gc();     } } 从打印结果可以看出当执行System.gc()方法后垃圾回收器只会回收那些仅仅持有弱引用的Key对象。id可以被3整除的Key对象持有强引用因此不会被回收。4.3用 WeakHashMap 堵住泄漏在 SocketManager 中防止泄漏很容易只要用 WeakHashMap 代替 HashMap 就行了。这里假定SocketManager不需要线程安全。当映射的生命周期必须与键的生命周期联系在一起时可以使用这种方法。用WeakHashMap修复 SocketManager。public class SocketManager {     private MapSocket,User m  new WeakHashMapSocket,User();         public void setUser(Socket s, User u) {         m.put(s, u);     }     public User getUser(Socket s) {         return m.get(s);     } } 4.4配合使用引用队列WeakHashMap 用弱引用承载映射键这使得应用程序不再使用键对象时它们可以被垃圾收集get() 实现可以根据 WeakReference.get() 是否返回 null 来区分死的映射和活的映射。但是这只是防止 Map 的内存消耗在应用程序的生命周期中不断增加所需要做的工作的一半还需要做一些工作以便在键对象被收集后从 Map 中删除死项。否则Map 会充满对应于死键的项。虽然这对于应用程序是不可见的但是它仍然会造成应用程序耗尽内存。引用队列是垃圾收集器向应用程序返回关于对象生命周期的信息的主要方法。弱引用有个构造函数取引用队列作为参数。如果用关联的引用队列创建弱引用在弱引用对象成为 GC 候选对象时这个引用对象就在引用清除后加入到引用队列中具体参考上文软引用示例。WeakHashMap 有一个名为 expungeStaleEntries() 的私有方法大多数 Map 操作中会调用它它去掉引用队列中所有失效的引用并删除关联的映射。5UML:使用关联类指明特定形式的引用关联类能够用来指明特定形式的引用如弱weak、软soft或虚 phantom引用。也可以如下的构造型方式。6参考资料[1]Thinking in Java4th[2]孙卫琴Java面向对象编程电子工业出版社2006[3]Robert Martin,UML for java programmers,2004[4] 通过Java软可及对象的重获提高程序性能张立明陈朔鹰程序员200308[5] Monica PawlanReference Objects and Garbage Collection,[url]http://java.sun.com/developer/technicalArticles/ALT/RefObj/[/url][6]Brian Goetz,Java 理论与实践: 用弱引用堵住内存泄漏,
http://www.yutouwan.com/news/435706/

相关文章:

  • 网站百度统计表格怎么做设计软件cad
  • 沈阳seo整站优化wordpress建站多个域名
  • 凡科网免费建站官网外包公司的优势和劣势
  • 网站开发方式三网合一网站建设方案
  • p2f网站系统太原做网站的公司网站建设
  • 如何制作一个网站基金培训网站
  • cmd iis重启单个网站成都网站建设服务商
  • 章丘区网站建设晋江网站建设报价
  • 嘉兴网站制作价格漳州市住房与城乡建设部网站
  • 网站济南网站建设Wordpress登录后顶部的黑
  • 搜狐快站做的手机网站sns网站是什么
  • 制作网站需要怎么做网站导航栏下面的文章
  • 珠海市企业网站制作品牌源码下载网站
  • 自适应型网站建设费用淘客网站怎么做百度
  • 郑州响应式网站上什么网站做会计教育
  • 服务好的郑州网站建设线上推广的渠道
  • 中国建设执业网站静态网页代码大全
  • 优质的天津网站建设零基础怎么建设网站
  • 医疗网站建设讯息网站优化文章
  • 做网站点wordpress最好的系统
  • 深圳app客户端做网站删除wordpress修订版本号
  • 网站建设简介淄博wordpress 代码模块
  • 建站公司平台上海快速建站平台
  • 免费网站空间php全球邮邮箱登录
  • 网站 seo 优化建议免费云虚拟主机
  • 商城版免费网站深圳网络推广公司有哪些
  • 开锁换锁做网站上海怎样做网站
  • 建设网站的目的服装类地方门户系统 哪家好
  • 上海专业做网站公司地址网络营销与直播专业学什么
  • 旅游网站建设模块兴仁县城乡建设局网站