成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java對象池技術(shù)的原理及其實現(xiàn)

開發(fā) 后端
Java對象的生命周期大致包括三個階段:對象的創(chuàng)建,對象的使用,對象的清除。

Java對象的生命周期分析

  Java對象的生命周期大致包括三個階段:對象的創(chuàng)建,對象的使用,對象的清除。因此,對象的生命周期長度可用如下的表達式表示:T = T1 + T2 +T3。其中T1表示對象的創(chuàng)建時間,T2表示對象的使用時間,而T3則表示其清除時間。由此,我們可以看出,只有T2是真正有效的時間,而T1、T3則是對象本身的開銷。下面再看看T1、T3在對象的整個生命周期中所占的比例。

  我們知道,Java對象是通過構(gòu)造函數(shù)來創(chuàng)建的,在這一過程中,該構(gòu)造函數(shù)鏈中的所有構(gòu)造函數(shù)也都會被自動調(diào)用。另外,默認情況下,調(diào)用類的構(gòu)造函數(shù)時,Java會把變量初始化成確定的值:所有的對象被設(shè)置成 null,整數(shù)變量(byte、short、int、long)設(shè)置成0,float和double變量設(shè)置成0.0,邏輯值設(shè)置成false。所以用 new關(guān)鍵字來新建一個對象的時間開銷是很大的,如表1所示。

  表1 一些操作所耗費時間的對照表

  1. 運算操作 示例 標準化時間   
  2. 本地賦值 i = n 1.0   
  3. 實例賦值 this.i = n 1.2   
  4. 方法調(diào)用 Funct() 5.9   
  5. 新建對象 New Object() 980   
  6. 新建數(shù)組 New int[10] 3100  

 從表1可以看出,新建一個對象需要980個單位的時間,是本地賦值時間的980倍,是方法調(diào)用時間的166倍,而若新建一個數(shù)組所花費的時間就更多了。

  再看清除對象的過程。我們知道,Java語言的一個優(yōu)勢,就是Java程序員勿需再像C/C++程序員那樣,顯式地釋放對象,而由稱為垃圾收集器(Garbage Collector)的自動內(nèi)存管理系統(tǒng),定時或在內(nèi)存凸現(xiàn)出不足時,自動回收垃圾對象所占的內(nèi)存。凡事有利總也有弊,這雖然為Java程序設(shè)計者提供了極大的方便,但同時它也帶來了較大的性能開銷。這種開銷包括兩方面,首先是對象管理開銷,GC為了能夠正確釋放對象,它必須監(jiān)控每一個對象的運行狀態(tài),包括對象的申請、引用、被引用、賦值等。其次,在GC開始回收“垃圾”對象時,系統(tǒng)會暫停應(yīng)用程序的執(zhí)行,而獨自占用CPU。

  因此,如果要改善應(yīng)用程序的性能,一方面應(yīng)盡量減少創(chuàng)建新對象的次數(shù);同時,還應(yīng)盡量減少T1、T3的時間,而這些均可以通過對象池技術(shù)來實現(xiàn)。

  對象池技術(shù)的基本原理

  對象池技術(shù)基本原理的核心有兩點:緩存和共享,即對于那些被頻繁使用的對象,在使用完后,不立即將它們釋放,而是將它們緩存起來,以供后續(xù)的應(yīng)用程序重復(fù)使用,從而減少創(chuàng)建對象和釋放對象的次數(shù),進而改善應(yīng)用程序的性能。事實上,由于對象池技術(shù)將對象限制在一定的數(shù)量,也有效地減少了應(yīng)用程序內(nèi)存上的開銷。

  實現(xiàn)一個對象池,一般會涉及到如下的類:

  1)對象池工廠(ObjectPoolFactory)類

  該類主要用于管理相同類型和設(shè)置的對象池(ObjectPool),它一般包含如下兩個方法:

  ·createPool:用于創(chuàng)建特定類型和設(shè)置的對象池;

  ·destroyPool:用于釋放指定的對象池;

  同時為保證ObjectPoolFactory的單一實例,可以采用Singleton設(shè)計模式,見下述getInstance方法的實現(xiàn):

  1. public static ObjectPoolFactory getInstance() {   
  2.  if (poolFactory == null) {   
  3.   poolFactory = new ObjectPoolFactory();   
  4.  }   
  5.  return poolFactory;   
  6. }   

  2)參數(shù)對象(ParameterObject)類

  該類主要用于封裝所創(chuàng)建對象池的一些屬性參數(shù),如池中可存放對象的數(shù)目的最大值(maxCount)、最小值(minCount)等。

  3)對象池(ObjectPool)類

  用于管理要被池化對象的借出和歸還,并通知PoolableObjectFactory完成相應(yīng)的工作。它一般包含如下兩個方法:

   ·getObject:用于從池中借出對象;
   ·returnObject:將池化對象返回到池中,并通知所有處于等待狀態(tài)的線程;

  4)池化對象工廠(PoolableObjectFactory)類

  該類主要負責管理池化對象的生命周期,就簡單來說,一般包括對象的創(chuàng)建及銷毀。該類同ObjectPoolFactory一樣,也可將其實現(xiàn)為單實例。
 通用對象池的實現(xiàn)

  對象池的構(gòu)造和管理可以按照多種方式實現(xiàn)。最靈活的方式是將池化對象的Class類型在對象池之外指定,即在ObjectPoolFactory類創(chuàng)建對象池時,動態(tài)指定該對象池所池化對象的Class類型,其實現(xiàn)代碼如下:

  1. . . .   
  2. public ObjectPool createPool(ParameterObject paraObj,Class clsType) {   
  3.  return new ObjectPool(paraObj, clsType);   
  4. }   
  5. . . .  


  其中,paraObj參數(shù)用于指定對象池的特征屬性,clsType參數(shù)則指定了該對象池所存放對象的類型。對象池(ObjectPool)創(chuàng)建以后,下面就是利用它來管理對象了,具體實現(xiàn)如下:
 

  1. public class ObjectPool {   
  2.  private ParameterObject paraObj;//該對象池的屬性參數(shù)對象   
  3.  private Class clsType;//該對象池中所存放對象的類型   
  4.  private int currentNum = 0//該對象池當前已創(chuàng)建的對象數(shù)目   
  5.  private Object currentObj;//該對象池當前可以借出的對象   
  6.  private Vector pool;//用于存放對象的池   
  7.  public ObjectPool(ParameterObject paraObj, Class clsType) {   
  8.   this.paraObj = paraObj;   
  9.   this.clsType = clsType;   
  10.   pool = new Vector();   
  11.  }   
  12.  public Object getObject() {   
  13.   if (pool.size() <= paraObj.getMinCount()) {   
  14.    if (currentNum <= paraObj.getMaxCount()) {   
  15.     //如果當前池中無對象可用,而且已創(chuàng)建的對象數(shù)目小于所限制的最大值,就利用   
  16.     //PoolObjectFactory創(chuàng)建一個新的對象   
  17.     PoolableObjectFactory objFactory =PoolableObjectFactory.getInstance();   
  18.     currentObj = objFactory.create Object (clsType);   
  19.     currentNum++;   
  20.    } else {   
  21.     //如果當前池中無對象可用,而且所創(chuàng)建的對象數(shù)目已達到所限制的最大值,   
  22.     //就只能等待其它線程返回對象到池中   
  23.     synchronized (this) {   
  24.      try {   
  25.       wait();   
  26.      } catch (InterruptedException e) {   
  27.       System.out.println(e.getMessage());   
  28.       e.printStackTrace();   
  29.      }   
  30.      currentObj = pool.firstElement();   
  31.     }   
  32.    }   
  33.   } else {   
  34.    //如果當前池中有可用的對象,就直接從池中取出對象   
  35.    currentObj = pool.firstElement();   
  36.   }   
  37.   return currentObj;   
  38. }   
  39.   public void returnObject(Object obj) {   
  40.    // 確保對象具有正確的類型   
  41.    if (obj.isInstance(clsType)) {   
  42.     pool.addElement(obj);   
  43.     synchronized (this) {   
  44.      notifyAll();   
  45.     }   
  46.    } else {   
  47.     throw new IllegalArgumentException("該對象池不能存放指定的對象類型");   
  48.    }   
  49.   }   
  50. }   


  從上述代碼可以看出,ObjectPool利用一個java.util.Vector作為可擴展的對象池,并通過它的構(gòu)造函數(shù)來指定池化對象的 Class類型及對象池的一些屬性。在有對象返回到對象池時,它將檢查對象的類型是否正確。當對象池里不再有可用對象時,它或者等待已被使用的池化對象返回池中,或者創(chuàng)建一個新的對象實例。不過,新對象實例的創(chuàng)建并不在ObjectPool類中,而是由PoolableObjectFactory類的 createObject方法來完成的,具體實現(xiàn)如下:

  1. . . .   
  2. public Object createObject(Class clsType) {   
  3.  Object obj = null;   
  4.  try {   
  5.   obj = clsType.newInstance();   
  6.  } catch (Exception e) {   
  7.   e.printStackTrace();   
  8.  }   
  9.  return obj;   
  10. }   
  11. . . .   



  這樣,通用對象池的實現(xiàn)就算完成了,下面再看看客戶端(Client)如何來使用它,假定池化對象的Class類型為StringBuffer:

 

  1. . . .   
  2. //創(chuàng)建對象池工廠   
  3. ObjectPoolFactory poolFactory = ObjectPoolFactory. getInstance ();   
  4. //定義所創(chuàng)建對象池的屬性   
  5. ParameterObject paraObj = new ParameterObject(2,1);   
  6. //利用對象池工廠,創(chuàng)建一個存放StringBuffer類型對象的對象池   
  7. ObjectPool pool = poolFactory.createPool(paraObj,String Buffer.class);   
  8. //從池中取出一個StringBuffer對象   
  9. StringBuffer buffer = (StringBuffer)pool.getObject();   
  10. //使用從池中取出的StringBuffer對象   
  11. buffer.append("hello");   
  12. System.out.println(buffer.toString());   
  13. . . .   


  可以看出,通用對象池使用起來還是很方便的,不僅可以方便地避免頻繁創(chuàng)建對象的開銷,而且通用程度高。但遺憾的是,由于需要使用大量的類型定型(cast)操作,再加上一些對Vector類的同步操作,使得它在某些情況下對性能的改進非常有限,尤其對那些創(chuàng)建周期比較短的對象。
專用對象池的實現(xiàn)     

  由于通用對象池的管理開銷比較大,某種程度上抵消了重用對象所帶來的大部分優(yōu)勢。為解決該問題,可以采用專用對象池的方法。即對象池所池化對象的Class類型不是動態(tài)指定的,而是預(yù)先就已指定。這樣,它在實現(xiàn)上也會較通用對象池簡單些,可以不要ObjectPoolFactory和PoolableObjectFactory類,而將它們的功能直接融合到ObjectPool類,具體如下(假定被池化對象的Class類型仍為StringBuffer,而用省略號表示的地方,表示代碼同通用對象池的實現(xiàn)):

  1. public class ObjectPool {   
  2.  private ParameterObject paraObj;//該對象池的屬性參數(shù)對象   
  3.  private int currentNum = 0//該對象池當前已創(chuàng)建的對象數(shù)目   
  4.  private StringBuffer currentObj;//該對象池當前可以借出的對象   
  5.  private Vector pool;//用于存放對象的池   
  6.  public ObjectPool(ParameterObject paraObj) {   
  7.   this.paraObj = paraObj;   
  8.   pool = new Vector();   
  9.  }   
  10.  public StringBuffer getObject() {   
  11.   if (pool.size() <= paraObj.getMinCount()) {   
  12.    if (currentNum <= paraObj.getMaxCount()) {   
  13.     currentObj = new StringBuffer();   
  14.     currentNum++;   
  15.    }   
  16.    . . .   
  17.   }   
  18.   return currentObj;   
  19.  }   
  20.  public void returnObject(Object obj) {   
  21.   // 確保對象具有正確的類型   
  22.   if (StringBuffer.isInstance(obj)) {   
  23.    . . .   
  24.   }   
  25.  }   


  結(jié)束語

  恰當?shù)厥褂脤ο蟪丶夹g(shù),能有效地改善應(yīng)用程序的性能。目前,對象池技術(shù)已得到廣泛的應(yīng)用,如對于網(wǎng)絡(luò)和數(shù)據(jù)庫連接這類重量級的對象,一般都會采用對象池技術(shù)。但在使用對象池技術(shù)時也要注意如下問題:

  并非任何情況下都適合采用對象池技術(shù)?;旧?,只在重復(fù)生成某種對象的操作成為影響性能的關(guān)鍵因素的時候,才適合采用對象池技術(shù)。而如果進行池化所能帶來的性能提高并不重要的話,還是不采用對象池化技術(shù)為佳,以保持代碼的簡明。

  要根據(jù)具體情況正確選擇對象池的實現(xiàn)方式。如果是創(chuàng)建一個公用的對象池技術(shù)實現(xiàn)包,或需要在程序中動態(tài)指定所池化對象的Class類型時,才選擇通用對象池。而大部分情況下,采用專用對象池就可以了。

【編輯推薦】

  1. Java序列化的機制和原理
  2. Java Socket通信的序列化和反序列化代碼介紹
  3. Java輸入數(shù)據(jù)流詳解
  4. Java語言深入 文件和流
  5. Java對象序列化

 

責任編輯:金賀 來源: JavaEye博客
相關(guān)推薦

2023-10-30 13:31:22

Springboot工具Java

2017-11-22 10:53:22

2020-09-25 08:49:42

HashMap

2011-04-22 13:10:46

計算機邏輯門

2015-11-03 09:24:12

Java讀寫鎖分析

2012-09-10 10:39:04

IBMdw

2021-10-31 23:57:33

Eslint原理

2024-06-04 09:02:03

2009-07-10 14:55:34

2024-04-24 08:32:55

.NET對象映射

2018-10-31 15:54:47

Java線程池源碼

2020-10-29 10:47:25

云計算容量管理

2015-11-30 11:14:59

C++對象池自動回收

2010-01-06 16:22:53

第三層交換技術(shù)

2021-05-26 11:30:24

Java線程池代碼

2011-07-08 09:21:01

域控制器主域控制器額外域控制器

2019-04-01 08:15:21

Java線程池多核處理器

2018-05-25 14:51:42

敏捷軟件開發(fā)測試

2019-11-27 10:31:51

數(shù)據(jù)庫連接池內(nèi)存

2022-05-24 12:34:32

Docker容器Linux容器進程
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 91久色| 久久国产一区二区三区 | 日本 欧美 国产 | 亚洲综合成人网 | jizz18国产| 男人天堂网址 | 亚洲精品久久久久久一区二区 | 精品久久久久一区 | 国产精品国产a | 激情欧美日韩一区二区 | 麻豆精品国产91久久久久久 | 久久成人在线视频 | 久久久久亚洲 | 免费爱爱视频 | 黄久久久 | av网站免费看 | 日韩电影一区 | 欧美在线a| 99精品久久 | 日韩精品免费一区二区在线观看 | 色播久久 | 国产一区二区视频免费在线观看 | 日本午夜一区二区三区 | 天天拍夜夜爽 | 在线视频一区二区三区 | 国产精品久久久久久一区二区三区 | 欧美在线国产精品 | 蜜臀91视频 | 日韩av福利在线观看 | 精品国产一区久久 | 欧美二区三区 | 欧美日韩亚洲国产 | 欧美一级特黄aaa大片在线观看 | 韩国av电影网 | 日韩一二三| 中文字幕视频在线 | 精品国产一区二区三区四区在线 | 中文字幕的av | 国产精品视频一区二区三区 | 国产玖玖 | 91精品综合久久久久久五月天 |