一樣的男人,不一樣的思想,造就不一樣的人生

          心胸有多大,舞臺(tái)就有多大

           

          2006年1月8日

          JAVA上傳文件

          轉(zhuǎn)載至翰血寶碼 http://lecky.tianyablog.com
          commons fileupload 是Apache commons項(xiàng)目的一部分,F(xiàn)ileUpload 使你很容易在servlet及web 應(yīng)用中提供一個(gè)魯棒的、高性能的文件上特性。FileUpload按照RFC 1867 ( "Form-based File Upload in HTML")處理HTTP請(qǐng)求。即,如果HTTP request 以 POST方法提交,并且content type 設(shè)置為"multipart/form-data",那么FileUpload可以處理該請(qǐng)求,在web應(yīng)用中提供文件上載的功能。其使用方法見commons fileupload的相關(guān)文檔。
          
           在把FileUpload與struts結(jié)合(jsp + uploadactiono)使用過程中發(fā)現(xiàn),如果在action mapping配置中不指定formbean,文件上傳過程正常。如果指定了formbean,文件上傳不正常,取不到文件。以下是幾個(gè)文件片斷:
          
          upload.jsp
          
          **form action="uploadaction.do?method=uploadByFileUpload" method="post" enctype="multipart/form-data" ** **input type="file" name="uploadfile"** **/form**UploadAction.java public ActionForward uploadByFileUpload(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { ......
           String dir =
           request.getSession().getServletContext().getRealPath(
           "/");
           DiskFileUpload fu= new DiskFileUpload();
          
           fu.setSizeMax( UPLOAD_MAXSIZE);
           fu.setSizeThreshold( MAX_DATA_IN_MEM);
           fu.setRepositoryPath( System.getProperty("java.io.tmpdir"));
          
           try {
           List fileItem= fu.parseRequest( request);
           Iterator it= fileItem.iterator();
           while( it.hasNext()){
           FileItem item= (FileItem)it.next();
           if( !item.isFormField() && null!= item.getName() &&
           0!= item.getName().trim().length()){
           String clientPath = item.getName();
           String fileName = new File(clientPath).getName();
          
           File destDir = new File( dir);
          
           File file = new File(destDir, fileName);
           item.write( file);
           map.put( item.getFieldName(),
           dir+ File.separator+ fileName);
          
          
           }
           }
           } catch (Exception e) {
           String str= "文件上載異常,錯(cuò)誤信息:"+ e.getMessage();
           System.out.println(str);
           throw new Exception( str, e);
           }
          
           ......
           }
          
          struts-config.xml
          
           name="TestForm"
           type="UploadAction"
           parameter="method" >
          
          
          
          現(xiàn)象:在struts-config.xml文件中,如果指定了formbean——name="TestForm" ,則文件無法正確上傳,UploadAction中的fu.parseRequest( request)方法返回值為null;如果去掉了說明formbean的name屬性,則文件可以正常上傳。
          
          原因:struts的RequestProccessor.process已經(jīng)包含了處理文件上傳的方法。如果在action配置中設(shè)置了formbean ,那么在你自己的action處理request之前,struts已經(jīng)在RequestProccessor.populate方法中處理了request,因此,在自己的action中就取不到上傳的文件了。
          
          處理:如果要自己在action中處理文件上傳工作,那么就不要在配置文件中配置formbean。
          
          其他選擇:如果仍需使用formbean,那么可以使用struts內(nèi)置的文件上傳功能。具體使用方法見struts的相關(guān)文檔,以及struts的upload例子。以下是幾個(gè)文件片斷:
          
          upload.jsp
          基本同上,修改form標(biāo)簽的action屬性
          
          
          UploadAction.java
           public ActionForward uploadByStruts(ActionMapping mapping,
           ActionForm form,
           HttpServletRequest request,
           HttpServletResponse response)
           throws Exception {
           ActionErrors errs= new ActionErrors();
          
           if (form != null){
           DynaActionForm theForm = (DynaActionForm)form;
           FormFile file = (FormFile)theForm.get("uploadfile");
           try{
           String fileName= file.getFileName();
           if ("".equals(fileName)) {return null;}
           InputStream stream = file.getInputStream();
          
           String dir =
           request.getSession().getServletContext().getRealPath(
           "/");
           OutputStream bos = new FileOutputStream(dir+"/"+fileName);
           int bytesRead = 0;
           byte[] buffer = new byte[8192];
           while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {
           bos.write(buffer, 0, bytesRead);
           }
           bos.close();
           stream.close();
           }catch (FileNotFoundException fnfe) {
           ...
           }catch (IOException ioe) {
           ...
           }catch (NullPointerException e){
           ...
           }
          
           }else{
           ...
           }
          
           if (!errs.isEmpty()){
           saveErrors( request, errs);
           }
          
           return mapping.findForward( "success");
          
           }
          
          
          struts-config.xml
          
          **form-bean name="TestForm" type="org.apache.struts.action.DynaActionForm"**
           form-property name="uploadfile" type="org.apache.struts.upload.FormFile" /**
           /form-bean**
          
           **action path="/uploadaction"
           name="TestForm" **!--指定formbean--**
           type="UploadAction"
           parameter="method" **
           **forward name="success" path="/success.jsp" /**
           **/action**
          
           **controller maxFileSize="2M" /**
          
          注意,使用struts自帶的文件上傳功能,最帶文件尺寸限制用來配置。另為struts對(duì)文件上載功能提供了兩種處理實(shí)現(xiàn):org.apache.struts.upload.CommonsMultipartRequestHandler 和 org.apache.struts.upload.DiskMultipartRequestHandler。struts默認(rèn)的是前者,如果要使用后者,需在中配置,配置樣例如下。而且,DiskMultipartRequestHandler是使用commons uploadload實(shí)現(xiàn)的。

          posted @ 2006-01-18 21:19 大夯 閱讀(1419) | 評(píng)論 (0)編輯 收藏

          Java本質(zhì)論之關(guān)于Java棧與堆的思考

          原文地址 http://www.tyl.cn/edu/ShowArticle.asp?ArticleID=1539

          1. 棧(stack)與堆(heap)都是Java用來在Ram中存放數(shù)據(jù)的地方。與C++不同,Java自動(dòng)管理?xiàng):投眩绦騿T不能直接地設(shè)置棧或堆。

          2. 棧的優(yōu)勢(shì)是,存取速度比堆要快,僅次于直接位于CPU中的寄存器。但缺點(diǎn)是,存在棧中的數(shù)據(jù)大小與生存期必須是確定的,缺乏靈活性。另外,棧數(shù)據(jù)可以共享,詳見第3點(diǎn)。堆的優(yōu)勢(shì)是可以動(dòng)態(tài)地分配內(nèi)存大小,生存期也不必事先告訴編譯器,Java的垃圾收集器會(huì)自動(dòng)收走這些不再使用的數(shù)據(jù)。但缺點(diǎn)是,由于要在運(yùn)行時(shí)動(dòng)態(tài)分配內(nèi)存,存取速度較慢。

          3. Java中的數(shù)據(jù)類型有兩種。

          一種是基本類型(primitive types), 共有8種,即int, short, long, byte, float, double, boolean, char(注意,并沒有string的基本類型)。這種類型的定義是通過諸如int a = 3; long b = 255L;的形式來定義的,稱為自動(dòng)變量。值得注意的是,自動(dòng)變量存的是字面值,不是類的實(shí)例,即不是類的引用,這里并沒有類的存在。如int a = 3; 這里的a是一個(gè)指向int類型的引用,指向3這個(gè)字面值。這些字面值的數(shù)據(jù),由于大小可知,生存期可知(這些字面值固定定義在某個(gè)程序塊里面,程序塊退出后,字段值就消失了),出于追求速度的原因,就存在于棧中。

          另外,棧有一個(gè)很重要的特殊性,就是存在棧中的數(shù)據(jù)可以共享。假設(shè)我們同時(shí)定義:

          int a = 3;
          int b = 3;

          編譯器先處理int a = 3;首先它會(huì)在棧中創(chuàng)建一個(gè)變量為a的引用,然后查找有沒有字面值為3的地址,沒找到,就開辟一個(gè)存放3這個(gè)字面值的地址,然后將a指向3的地址。接著處理int b = 3;在創(chuàng)建完b的引用變量后,由于在棧中已經(jīng)有3這個(gè)字面值,便將b直接指向3的地址。這樣,就出現(xiàn)了a與b同時(shí)均指向3的情況。

          特別注意的是,這種字面值的引用與類對(duì)象的引用不同。假定兩個(gè)類對(duì)象的引用同時(shí)指向一個(gè)對(duì)象,如果一個(gè)對(duì)象引用變量修改了這個(gè)對(duì)象的內(nèi)部狀態(tài),那么另一個(gè)對(duì)象引用變量也即刻反映出這個(gè)變化。相反,通過字面值的引用來修改其值,不會(huì)導(dǎo)致另一個(gè)指向此字面值的引用的值也跟著改變的情況。如上例,我們定義完a與b的值后,再令a=4;那么,b不會(huì)等于4,還是等于3。在編譯器內(nèi)部,遇到a=4;時(shí),它就會(huì)重新搜索棧中是否有4的字面值,如果沒有,重新開辟地址存放4的值;如果已經(jīng)有了,則直接將a指向這個(gè)地址。因此a值的改變不會(huì)影響到b的值。

          另一種是包裝類數(shù)據(jù),如Integer, String, Double等將相應(yīng)的基本數(shù)據(jù)類型包裝起來的類。這些類數(shù)據(jù)全部存在于堆中,Java用new()語(yǔ)句來顯示地告訴編譯器,在運(yùn)行時(shí)才根據(jù)需要?jiǎng)討B(tài)創(chuàng)建,因此比較靈活,但缺點(diǎn)是要占用更多的時(shí)間。 4. String是一個(gè)特殊的包裝類數(shù)據(jù)。即可以用String str = new String("abc");的形式來創(chuàng)建,也可以用String str = "abc";的形式來創(chuàng)建(作為對(duì)比,在JDK 5.0之前,你從未見過Integer i = 3;的表達(dá)式,因?yàn)轭惻c字面值是不能通用的,除了String。而在JDK 5.0中,這種表達(dá)式是可以的!因?yàn)榫幾g器在后臺(tái)進(jìn)行Integer i = new Integer(3)的轉(zhuǎn)換)。前者是規(guī)范的類的創(chuàng)建過程,即在Java中,一切都是對(duì)象,而對(duì)象是類的實(shí)例,全部通過new()的形式來創(chuàng)建。Java中的有些類,如DateFormat類,可以通過該類的getInstance()方法來返回一個(gè)新創(chuàng)建的類,似乎違反了此原則。其實(shí)不然。該類運(yùn)用了單例模式來返回類的實(shí)例,只不過這個(gè)實(shí)例是在該類內(nèi)部通過new()來創(chuàng)建的,而getInstance()向外部隱藏了此細(xì)節(jié)。那為什么在String str = "abc";中,并沒有通過new()來創(chuàng)建實(shí)例,是不是違反了上述原則?其實(shí)沒有。

          5. 關(guān)于String str = "abc"的內(nèi)部工作。Java內(nèi)部將此語(yǔ)句轉(zhuǎn)化為以下幾個(gè)步驟:

          (1)先定義一個(gè)名為str的對(duì)String類的對(duì)象引用變量:String str;

          (2)在棧中查找有沒有存放值為"abc"的地址,如果沒有,則開辟一個(gè)存放字面值為"abc"的地址,接著創(chuàng)建一個(gè)新的String類的對(duì)象o,并將o的字符串值指向這個(gè)地址,而且在棧中這個(gè)地址旁邊記下這個(gè)引用的對(duì)象o。如果已經(jīng)有了值為"abc"的地址,則查找對(duì)象o,并返回o的地址。

          (3)將str指向?qū)ο髈的地址。

          值得注意的是,一般String類中字符串值都是直接存值的。但像String str = "abc";這種場(chǎng)合下,其字符串值卻是保存了一個(gè)指向存在棧中數(shù)據(jù)的引用!

          為了更好地說明這個(gè)問題,我們可以通過以下的幾個(gè)代碼進(jìn)行驗(yàn)證。

          String str1 = "abc";
          String str2 = "abc";
          System.out.println(str1==str2); //true

          注意,我們這里并不用str1.equals(str2);的方式,因?yàn)檫@將比較兩個(gè)字符串的值是否相等。==號(hào),根據(jù)JDK的說明,只有在兩個(gè)引用都指向了同一個(gè)對(duì)象時(shí)才返回真值。而我們?cè)谶@里要看的是,str1與str2是否都指向了同一個(gè)對(duì)象。
          結(jié)果說明,JVM創(chuàng)建了兩個(gè)引用str1和str2,但只創(chuàng)建了一個(gè)對(duì)象,而且兩個(gè)引用都指向了這個(gè)對(duì)象。

          我們?cè)賮砀M(jìn)一步,將以上代碼改成:

          String str1 = "abc";
          String str2 = "abc";
          str1 = "bcd";
          System.out.println(str1 + "," + str2); //bcd, abc
          System.out.println(str1==str2); //false

          這就是說,賦值的變化導(dǎo)致了類對(duì)象引用的變化,str1指向了另外一個(gè)新對(duì)象!而str2仍舊指向原來的對(duì)象。上例中,當(dāng)我們將str1的值改為"bcd"時(shí),JVM發(fā)現(xiàn)在棧中沒有存放該值的地址,便開辟了這個(gè)地址,并創(chuàng)建了一個(gè)新的對(duì)象,其字符串的值指向這個(gè)地址。

          事實(shí)上,String類被設(shè)計(jì)成為不可改變(immutable)的類。如果你要改變其值,可以,但JVM在運(yùn)行時(shí)根據(jù)新值悄悄創(chuàng)建了一個(gè)新對(duì)象,然后將這個(gè)對(duì)象的地址返回給原來類的引用。這個(gè)創(chuàng)建過程雖說是完全自動(dòng)進(jìn)行的,但它畢竟占用了更多的時(shí)間。在對(duì)時(shí)間要求比較敏感的環(huán)境中,會(huì)帶有一定的不良影響。

          再修改原來代碼:

          String str1 = "abc";
          String str2 = "abc";

          str1 = "bcd";

          String str3 = str1;
          System.out.println(str3); //bcd

          String str4 = "bcd";
          System.out.println(str1 == str4); //true

          str3這個(gè)對(duì)象的引用直接指向str1所指向的對(duì)象(注意,str3并沒有創(chuàng)建新對(duì)象)。當(dāng)str1改完其值后,再創(chuàng)建一個(gè)String的引用str4,并指向因str1修改值而創(chuàng)建的新的對(duì)象。可以發(fā)現(xiàn),這回str4也沒有創(chuàng)建新的對(duì)象,從而再次實(shí)現(xiàn)棧中數(shù)據(jù)的共享。

          我們?cè)俳又匆韵碌拇a。

          String str1 = new String("abc");
          String str2 = "abc";
          System.out.println(str1==str2); //false

          創(chuàng)建了兩個(gè)引用。創(chuàng)建了兩個(gè)對(duì)象。兩個(gè)引用分別指向不同的兩個(gè)對(duì)象。

          String str1 = "abc";
          String str2 = new String("abc");
          System.out.println(str1==str2); //false

          創(chuàng)建了兩個(gè)引用。創(chuàng)建了兩個(gè)對(duì)象。兩個(gè)引用分別指向不同的兩個(gè)對(duì)象。

          以上兩段代碼說明,只要是用new()來新建對(duì)象的,都會(huì)在堆中創(chuàng)建,而且其字符串是單獨(dú)存值的,即使與棧中的數(shù)據(jù)相同,也不會(huì)與棧中的數(shù)據(jù)共享。

          6. 數(shù)據(jù)類型包裝類的值不可修改。不僅僅是String類的值不可修改,所有的數(shù)據(jù)類型包裝類都不能更改其內(nèi)部的值。 7. 結(jié)論與建議:

          (1)我們?cè)谑褂弥T如String str = "abc";的格式定義類時(shí),總是想當(dāng)然地認(rèn)為,我們創(chuàng)建了String類的對(duì)象str。擔(dān)心陷阱!對(duì)象可能并沒有被創(chuàng)建!唯一可以肯定的是,指向String類的引用被創(chuàng)建了。至于這個(gè)引用到底是否指向了一個(gè)新的對(duì)象,必須根據(jù)上下文來考慮,除非你通過new()方法來顯要地創(chuàng)建一個(gè)新的對(duì)象。因此,更為準(zhǔn)確的說法是,我們創(chuàng)建了一個(gè)指向String類的對(duì)象的引用變量str,這個(gè)對(duì)象引用變量指向了某個(gè)值為"abc"的String類。清醒地認(rèn)識(shí)到這一點(diǎn)對(duì)排除程序中難以發(fā)現(xiàn)的bug是很有幫助的。

          (2)使用String str = "abc";的方式,可以在一定程度上提高程序的運(yùn)行速度,因?yàn)镴VM會(huì)自動(dòng)根據(jù)棧中數(shù)據(jù)的實(shí)際情況來決定是否有必要?jiǎng)?chuàng)建新對(duì)象。而對(duì)于String str = new String("abc");的代碼,則一概在堆中創(chuàng)建新對(duì)象,而不管其字符串值是否相等,是否有必要?jiǎng)?chuàng)建新對(duì)象,從而加重了程序的負(fù)擔(dān)。這個(gè)思想應(yīng)該是享元模式的思想,但JDK的內(nèi)部在這里實(shí)現(xiàn)是否應(yīng)用了這個(gè)模式,不得而知。

          (3)當(dāng)比較包裝類里面的數(shù)值是否相等時(shí),用equals()方法;當(dāng)測(cè)試兩個(gè)包裝類的引用是否指向同一個(gè)對(duì)象時(shí),用==。

          (4)由于String類的immutable性質(zhì),當(dāng)String變量需要經(jīng)常變換其值時(shí),應(yīng)該考慮使用StringBuffer類,以提高程序效率。

          posted @ 2006-01-08 00:59 大夯 閱讀(484) | 評(píng)論 (1)編輯 收藏

          論java內(nèi)存泄露問題

          這幾天服務(wù)器碰到了內(nèi)存泄漏的問題,就從網(wǎng)上找了篇看了一下希望對(duì)大家有一定的參考價(jià)值。
          (原文地址http://www.tyl.cn/edu/ShowArticle.asp?ArticleID=1548

          內(nèi)存泄漏的慨念
          1.c/c++是程序員自己管理內(nèi)存,Java內(nèi)存是由GC自動(dòng)回收的。

          我雖然不是很熟悉C++,不過這個(gè)應(yīng)該沒有犯常識(shí)性錯(cuò)誤吧。

          2.什么是內(nèi)存泄露?

          內(nèi)存泄露是指系統(tǒng)中存在無法回收的內(nèi)存,有時(shí)候會(huì)造成內(nèi)存不足或系統(tǒng)崩潰。

          在C/C++中分配了內(nèi)存不釋放的情況就是內(nèi)存泄露。

          3.Java存在內(nèi)存泄露

          我們必須先承認(rèn)這個(gè),才可以接著討論。雖然Java存在內(nèi)存泄露,但是基本上不用很關(guān)心它,特別是那些對(duì)代碼本身就不講究的就更不要去關(guān)心這個(gè)了。

          Java中的內(nèi)存泄露當(dāng)然是指:存在無用但是垃圾回收器無法回收的對(duì)象。而且即使有內(nèi)存泄露問題存在,也不一定會(huì)表現(xiàn)出來。

          4.Java中參數(shù)都是傳值的。

          對(duì)于基本類型,大家基本上沒有異議,但是對(duì)于引用類型我們也不能有異議。

          Java內(nèi)存泄露情況
          JVM回收算法是很復(fù)雜的,我也不知道他們?cè)趺磳?shí)現(xiàn)的,但是我只知道他們要實(shí)現(xiàn)的就是:對(duì)于沒有被引用的對(duì)象是可以回收的。所以你要造成內(nèi)存泄露就要做到:

          持有對(duì)無用對(duì)象的引用!

          不要以為這個(gè)很容易做到,既然無用,你怎么還會(huì)持有它的引用? 既然你還持有它,它怎么會(huì)是無用的呢?

          我實(shí)在想不到比那個(gè)堆棧更經(jīng)典的例子了,以致于我還要引用別人的例子,下面的例子不是我想到的,是書上看到的,當(dāng)然如果沒有在書上看到,可能過一段時(shí)間我自己也想的到,可是那時(shí)我說是我自己想到的也沒有人相信的。

          public class Stack {
          private Object[] elements=new Object[10];
          private int size = 0;

          public void push(Object e){
          ensureCapacity();
          elements[size++] = e;
          }

          public Object pop(){
          if( size == 0)
          throw new EmptyStackException();
          return elements[--size];
          }

          private void ensureCapacity(){
          if(elements.length == size){
          Object[] oldElements = elements;
          elements = new Object[2 * elements.length+1];
          System.arraycopy(oldElements,0, elements, 0, size);
          }
          }
          }
          上面的原理應(yīng)該很簡(jiǎn)單,假如堆棧加了10個(gè)元素,然后全部彈出來,雖然堆棧是空的,沒有我們要的東西,但是這是個(gè)對(duì)象是無法回收的,這個(gè)才符合了內(nèi)存泄露的兩個(gè)條件:無用,無法回收。

          但是就是存在這樣的東西也不一定會(huì)導(dǎo)致什么樣的后果,如果這個(gè)堆棧用的比較少,也就浪費(fèi)了幾個(gè)K內(nèi)存而已,反正我們的內(nèi)存都上G了,哪里會(huì)有什么影響,再說這個(gè)東西很快就會(huì)被回收的,有什么關(guān)系。下面看兩個(gè)例子。

          例子1

          public class Bad{
          public static Stack s=Stack();
          static{
          s.push(new Object());
          s.pop(); //這里有一個(gè)對(duì)象發(fā)生內(nèi)存泄露
          s.push(new Object()); //上面的對(duì)象可以被回收了,等于是自愈了
          }
          }

          因?yàn)槭莝tatic,就一直存在到程序退出,但是我們也可以看到它有自愈功能,就是說如果你的Stack最多有100個(gè)對(duì)象,那么最多也就只有100個(gè)對(duì)象無法被回收其實(shí)這個(gè)應(yīng)該很容易理解,Stack內(nèi)部持有100個(gè)引用,最壞的情況就是他們都是無用的,因?yàn)槲覀円坏┓判碌倪M(jìn)取,以前的引用自然消失!

          例子2

          public class NotTooBad{
          public void doSomething(){
          Stack s=new Stack();
          s.push(new Object());
          //other code
          s.pop();//這里同樣導(dǎo)致對(duì)象無法回收,內(nèi)存泄露.
          }//退出方法,s自動(dòng)無效,s可以被回收,Stack內(nèi)部的引用自然沒了,所以
          //這里也可以自愈,而且可以說這個(gè)方法不存在內(nèi)存泄露問題,不過是晚一點(diǎn)
          //交給GC而已,因?yàn)樗欠忾]的,對(duì)外不開放,可以說上面的代碼99.9999%的
          //情況是不會(huì)造成任何影響的,當(dāng)然你寫這樣的代碼不會(huì)有什么壞的影響,但是
          //絕對(duì)可以說是垃圾代碼!沒有矛盾吧,我在里面加一個(gè)空的for循環(huán)也不會(huì)有
          //什么太大的影響吧,你會(huì)這么做嗎?
          }

          上面兩個(gè)例子都不過是小打小鬧,但是C/C++中的內(nèi)存泄露就不是Bad了,而是Worst了。他們?nèi)绻惶帥]有回收就永遠(yuǎn)無法回收,頻繁的調(diào)用這個(gè)方法內(nèi)存不就用光了!因?yàn)镴ava還有自愈功能(我自己起的名字,還沒申請(qǐng)專利),所以Java的內(nèi)存泄露問題幾乎可以忽略了,但是知道的人就不要犯了。

          不知者無罪!Java存在內(nèi)存泄露,但是也不要夸大其辭。如果你對(duì)Java都不是很熟,你根本就不用關(guān)心這個(gè),我說過你無意中寫出內(nèi)存泄露的例子就像你中一千萬(wàn)一樣概率小,開玩笑了,其實(shí)應(yīng)該是小的多的多!

          而且即使你有幸寫出這樣的代碼,中獎(jiǎng)了!基本上都是一包洗衣粉,不會(huì)讓你發(fā)財(cái),對(duì)系統(tǒng)沒有什么大的影響。

          杞人憂天的情況
          1.無話可說型

          Object obj=new Object();
          obj=null;
          //這個(gè)完全多此一舉,因?yàn)橥顺隽俗饔梅秶瑢?duì)象的引用自動(dòng)消失
          //不要在你的程序中出現(xiàn)這樣的語(yǔ)句,沒有錯(cuò),但是就是不雅觀

          2.思考不對(duì)型

          void func(Object o){
          o=new Object();
          return
          }

          當(dāng)我們知道Java參數(shù)是傳值,就知道上面的方法什么也沒錯(cuò),就是申請(qǐng)了一個(gè)對(duì)象然后再丟給GC。因?yàn)槭莻髦担@里的o是一個(gè)調(diào)用時(shí)候的拷貝,會(huì)不會(huì)無法回收?不就是拷貝嗎,退出方法什么都沒了,這個(gè)對(duì)象怎么會(huì)留的住。

          3.盡量避免型

          class A{
          B b=new B(this);
          }
          class B{
          A a;
          B(A a){this.a=a;}
          }

          這個(gè)存在互相引用,可能導(dǎo)致孤島現(xiàn)象,但是這個(gè)不會(huì)造成內(nèi)存泄露不過我自己覺得這個(gè)會(huì)降低GC的效率,就從我的智力來看,我覺得這種情況比一般情況難以判斷怎么回收!當(dāng)然GC比我聰明,不過應(yīng)該也要?jiǎng)右稽c(diǎn)腦子吧

          posted @ 2006-01-08 00:42 大夯 閱讀(332) | 評(píng)論 (0)編輯 收藏

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(1)

          隨筆檔案

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 黄浦区| 萨嘎县| 菏泽市| 华阴市| 阿坝| 泗阳县| 克东县| 岳普湖县| 库伦旗| 鹤山市| 吐鲁番市| 宁国市| 宜黄县| 正阳县| 石楼县| 凌海市| 卢湾区| 蒙山县| 东丽区| 平罗县| 财经| 嘉兴市| 丹阳市| 泗阳县| 宁夏| 乌兰县| 长阳| 琼海市| 淅川县| 苏尼特右旗| 宝山区| 织金县| 祥云县| 阜宁县| 兴仁县| 磴口县| 阳春市| 丁青县| 崇信县| 伊金霍洛旗| 平邑县|