对象引用与垃圾收集_第1页
对象引用与垃圾收集_第2页
对象引用与垃圾收集_第3页
对象引用与垃圾收集_第4页
对象引用与垃圾收集_第5页
已阅读5页,还剩63页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

对象引用与垃圾收集第1页,课件共68页,创作于2023年2月主题对象引用与垃圾收集异常处理JAVAI/O正则表达式利用JAVA进行XML编程嵌套式类对象的封装与继承抽象类与接口第2页,课件共68页,创作于2023年2月垃圾收集垃圾收集器的工作原理是识别程序中不再使用的对象,并且回收其内存。

第3页,课件共68页,创作于2023年2月垃圾收集J2SE1.4采用的代间收集策略第4页,课件共68页,创作于2023年2月垃圾收集JDK1.4的垃圾收集器 复制收集器、标记整理收集器、增量式收集器、并行复制收集器、并行清除(scavenging)收集器和并发标记-清除收集器。第5页,课件共68页,创作于2023年2月垃圾收集其他收集选项第6页,课件共68页,创作于2023年2月垃圾收集观察垃圾收集运行状况 有很多办法来监听垃圾回收器的活动。可用Xverbose:gc选项运行JVM,然后观察输出结果一段时间。

[memory]13.009-13.130:GC65536K->16788K(65536K),121.000ms第7页,课件共68页,创作于2023年2月垃圾收集微调垃圾收集选项 最简单的垃圾收集微调就是扩大最大堆的大小(-Xmx)。随着堆的增大,复制收集会变得更有效,所以在增大堆时,您就减少了每个对象的收集成本。除了增加最大堆的大小,还可以用选项-XX:NewRatio增加分配给年轻代的空间份额。也可以用-Xmn选项显式指定年轻代的大小。第8页,课件共68页,创作于2023年2月引用对象从JDK1.2开引入了一个引用对象应用程序接口API允许程序维持一个特别的到对象的引用,这样程序能够通过这一有限的途径和垃圾收集器进行交互。加入引用对象之后的引用与常规引用的区别在于,引用对象中的引用专门由内存管理器来处理。引用对象封装了其它一些对象的引用,我们称之为指示对象。在引用对象创建的同时,也就定义了该引用对象的指示对象。第9页,课件共68页,创作于2023年2月Heap中的引用对象ReferenceObjects第10页,课件共68页,创作于2023年2月ReferenceObjects类层次第11页,课件共68页,创作于2023年2月对象的引用层次根据对象的可获取程度:强获取、次获取、弱获取、虚获取根据应用程序要求,对象可以是强引用(strongreferences)、次引用(softreferences)、弱引用(weakreferences)、虚引用(phantomreferences)的任意组合。第12页,课件共68页,创作于2023年2月强引用(strongreference)JVM内存管理器从引用集合出发遍寻堆中所有到对象的路径。当到达某对象的任意路径都不含有引用对象时,则称该对象具有强获取能力。该对象为强引用对象Rootsetofreferencesstrongreferencesgarbage第13页,课件共68页,创作于2023年2月次引用(softreference)第14页,课件共68页,创作于2023年2月次引用(softreference)publicclassDisplayImageextendsApplet{SoftReferencesr=null;publicvoidinit(){System.out.println("Initializing");}publicvoidpaint(Graphicsg){Imageim=(sr==null)?null:(Image)(sr.get());if(im==null){System.out.println("Fetchingimage");im=getImage(getCodeBase(),"truck1.gif");sr=newSoftReference(im);}System.out.println("Painting");g.drawImage(im,25,25,this);im=null;}publicvoidstart(){}publicvoidstop(){};}}第15页,课件共68页,创作于2023年2月次引用(SoftReference)所有SoftReference到的对象保证会在java虚拟机发生OutOfMemoryError前被清除。SoftReference常被用来实现object-cache(memory-sensitivecaches)之用的。被SoftReference指到的对象,即使没有任何DirectReference,也不会被清除。一直要到JVM内存不足时且没有DirectReference时才会清除,如此一来SoftReference不但可以把对象cache起来,也不会造成内存不足的错误(OutOfMemoryError)。第16页,课件共68页,创作于2023年2月弱引用(weakreference)当内存管理器未发现strongreferences和softreferences时,我们称对象具有弱获取能力,即在到达该对象的路径中至少包含一个weakreference。第17页,课件共68页,创作于2023年2月弱引用(weakreference)弱引用(weakreferences)允许用来查询一个对象是否已被垃圾收集器回收。Imageim=(sr==null)?null:(Image)(sr.get());if(im==null){System.out.println("Fetchingimage");im=getImage(getCodeBase(),"truck1.gif");sr=newSoftReference(im);}第18页,课件共68页,创作于2023年2月publicclassWeakObj{ publicstaticvoidmain(String[]args){ try{ ReferenceQueueaReferenceQueue=newReferenceQueue(); ObjectanObject=newObject(); WeakReferenceref=newWeakReference(anObject, aReferenceQueue); StringextraData=newString("ExtraData"); HashMapaHashMap=newHashMap(); aHashMap.put(ref,extraData);//(key)inaHashMap anObject=null; if(anObject==null){ //ClearthestrongreferencetoextraData extraData=null; } }catch(Exceptione){ System.err.println("Anexceptionoccurred:");e.printStackTrace(); } }}第19页,课件共68页,创作于2023年2月weakreference分析SoftReference和WeakReference的不同在于前者是否会收集是由垃圾收集器的算法决定的,而后者是一定会被收集的。第20页,课件共68页,创作于2023年2月虚引用(PhantomReference)主要是用来取代对象的finalize()和WeakReference以及SoftReference最大的不同是:PhantomReference一订要搭配着ReferenceQueue使用,因为PhantomReference的get()传出值一定是null(以避免此对象不小心再度拥有DirectReference)。第21页,课件共68页,创作于2023年2月Java对象引用接口应用1. 基于Web的应用程序常常要求显示大量图片,当用户离开某一Web页时,往往不能确定是否能够顺利的返回。在这种程序中,应用Java对象引用API可以创建这样一个环境,即当堆内存以最小程度运行时,内存管理器创建对象。当用户返回时,应用程序就会重新载入已经创建的图片。第22页,课件共68页,创作于2023年2月Java对象引用接口应用2. 应用对象引用队列可以创建这样一个环境,当通过对象引用获得某一对象时,应用程序得到通知。然后,应用程序就可以对相关对象进行清除操作,同时使这些对象在内存管理器中合法化。第23页,课件共68页,创作于2023年2月内存泄漏内存泄露的本质是无用但仍被引用的对象。仅当一个对象不再被引用时才能被统计为无用的对象。垃圾收集器只能收集没有被应用程序引用的对象。第24页,课件共68页,创作于2023年2月无用但仍被引用的对象上面说明了在Java应用程序执行期间具有不同生存周期的两个类。类A首先被实例化,并会在很长一段时间或程序的整个生存期内存在。在某个时候,类B被创建,类A添加对这个新创建的类的一个引用。现在,我们假定类B是某个用户界面小部件,它由用户显示甚至解除。如果没有清除类A对B的引用,则即便不再需要类B,并且即便在执行下一个垃圾收集周期以后,类B仍将存在并占用内存空间。第25页,课件共68页,创作于2023年2月内存泄漏-无意识的对象保留publicclassStack{privateObject[]elements;privateintsize=0;publicStack(intinitialCapacity){this.elements=newObject[initialCapacity];}publicvoidpush(Objecte){ensureCapacity();elements[size++]=e;}publicObjectpop(){if(size==0)thrownewEmptyStackException();Objectresult=elements[--size];returnresult;}privatevoidensureCapacity(){if(elements.length==size){Object[]oldElements=elements;elements=newObject[2*elements.length+1]; System.arraycopy(oldElements,0,elements,0,size); }}}第26页,课件共68页,创作于2023年2月内存泄漏-错误的局部作用域staticStringBuffersb=newStringBuffer();publicstaticStringscopingExample(Stringstring){sb=newStringBuffer();sb.append("hello").append(string);sb.append(",nicetoseeyou!");returnsb.toString();}第27页,课件共68页,创作于2023年2月资源泄漏释放资源有一个简单的原则:如果有资源清理方法(colse、free)就及时调用。使用finally

避免资源泄漏(resourceleaks)finally构件使得某些代码总是得以被执行,无论是否发生异常。在维护对象内部状态和清理non-memory资源方面,finally尤其适用。第28页,课件共68页,创作于2023年2月资源泄漏-被放弃的JDBC对象Connectionconn=null;

try{

conn=getConnection();

for(inti=0;i<NUM_T;i++){

Statementstmt=null;

ResultSetrs=null;

stmt=conn.createStatement();

rs=stmt.executeQuery(/*somequery*/);

}

}catch(SQLExceptione){

//handleanyexceptions

}finally{

try{

if(conn!=null)

conn.close();

}catch(SQLExceptionignor){…}

}第29页,课件共68页,创作于2023年2月显示关闭资源 在finally块中显式关闭Connection、Statement和ResultSet对象,以确保无论是在正常还是异常情况下都将所有JDBC对象关闭。 try{

conn=JNDIUtils.getConnection(DS_NAME);

st=con.createStatement();

rs=st.executeQuery(query);

//对结果集操 }catch(Exceptione){ //handleexception }finally{ DbUtils.close(rs); DbUtils.close(st); DbUtils.close(conn); }第30页,课件共68页,创作于2023年2月J2EE容器中的连接池 尽管根据JDBC规范的规定,关闭Connection时正常情况下也会将Statement和ResultSet关闭,但不同的提供者都有具体的实现。建议用过资源要及时释放,避免对pool实现的依赖。特别地对于connection执行close时只是将该连接返还给连接池而已。第31页,课件共68页,创作于2023年2月异常处理-异常的继承构架Throwable

Error(严重的系统错误)

LinkageError

ThreadDeath

VirtualMachineError

....

Exception

ClassNotFoundException

CloneNotSupportedException

IllegalAccessException

....

RuntimeException(执行期异常)

ArithmeticException

ArrayStoreException

ClassCastException第32页,课件共68页,创作于2023年2月异常处理1.可以被抛出。2.可以被捕获。3.可以被程序化地创建。4.可以被JVM创建。5.被表示为第一级对象。6.继承的深度从3开始。7.由String(和来自1.4的StackTraceElements)组成。8.依靠本机方法fillInStackTrace()。第33页,课件共68页,创作于2023年2月异常处理异常处理的原则必须对异常有所作为当异常(exception)诞生时,如果你不捉(catch)它,会发生什么事呢?在Java中如果异常产生了却未被捕获,发生异常的那个线程(thread)将因而中断。所以你必须对你的代码所产生的异常有所作为。第34页,课件共68页,创作于2023年2月异常处理对异常的可作为方式:1.捕捉并处理它,防止它进㆒步传播(propagate)。2.捕捉并再次抛出它,这么㆒来它会被传播给调用端。3.捕捉它,然后抛出㆒个新异常给调用端。4.不捕捉这个异常,听任它传播给调用端。第35页,课件共68页,创作于2023年2月异常处理-千万不要遮掩异常publicvoidm1(){//...try{//CodethatcouldthrowaFileNotFoundException}catch(FileNotFoundExceptionfnfe){}//Theexceptionstopshere//...Restofcodeinmethod}第36页,课件共68页,创作于2023年2月异常处理-避免极度通用的处理方式意外地淹没RuntimeExceptiontry{ doSomething();}catch(Exceptione){ log(e);}第37页,课件共68页,创作于2023年2月异常处理-理解throws子句提供throws子句的用意在于,提醒函数调用者,告知可能发生的异常。当你给出throws子句的时候,要填写得完整无缺。虽然编译器不强求这样,但将 函数可能抛出的所有异常统统列出,是良好的编程习惯。第38页,课件共68页,创作于2023年2月异常处理-不完整的throws子句不完整的throws子句使调用者对真实的异常变得难于处理classException1extendsException{}classException2extendsException1{}classException3extendsException2{}classLazy{ publicvoidfoo(inti)throwsException1 { if(i==1) thrownewException1(); if(i==2) thrownewException2(); if(i==3) thrownewException3(); } }第39页,课件共68页,创作于2023年2月异常处理-Try区段的一个陷阱最好不要在catch块中返回值classFinallyTest{publicintmethod1(){ try{ return2; } catch(Exceptione){ return3; }}publicintmethod2(){ try{ return3; } finally{ return4; }}第40页,课件共68页,创作于2023年2月异常处理-不要将异常用于流程控制

将异常用于流程控制会使程序性能低下、含义模糊,难以维护classDoneWithLoopExceptionextendsException{}classTest{ publicvoidfoo(){ //... try{ while(true){ //Dosomething... if(someloopterminatingcondition) thrownewDoneWithLoopException(); } }catch(DoneWithLoopExceptione){} //... }}第41页,课件共68页,创作于2023年2月异常处理-不要滥用异常不要针对所有情形使用异常,应该将异常用于符合其意义的地方

intdata;MyInputStreamin=newMyInputStream("filename.ext");data=in.getData();while(data!=0){//Dosomethingwithdatadata=in.getData();}第42页,课件共68页,创作于2023年2月异常处理-不要滥用异常应该是面对不可预料的行为,才使用异常。

intdata;MyInputStreamin=newMyInputStream("filename.ext");try{ while(true){ data=in.getData(); //Dosomethingwithdata }}catch(NoMoreDataExceptione1){}第43页,课件共68页,创作于2023年2月异常处理-关于检查型异常和非检查型异常检查型异常代表关于一个合法指定的请求的操作的有用信息,调用者可能已经对该操作没有控制,并且调用者需要得到有关的通知——例如,文件系统已满,或者远端已经关闭连接,或者访问权限不允许该动作。第44页,课件共68页,创作于2023年2月异常处理-关于检查型异常和非检查型异常对于因为编程错误而导致的异常,或者是不能期望程序捕获的异常(解除引用一个空指针,数组越界,除零,等等),为了使开发人员免于处理这些异常,一些异常被命名为非检查型异常(即那些继承自RuntimeException的异常)并且不需要进行声明。第45页,课件共68页,创作于2023年2月JAVAI/OJava语言程序使用的数据必须来自某个地方。通常,这些数据来自一些外部数据源。有许多不同种类的数据源,其中包括数据库、套接字上的直接字节转换和文件等。Java语言提供了许多可以用来从外部数据源获得信息的工具。这些工具大部分都在java.io包中。第46页,课件共68页,创作于2023年2月JAVAI/O继承层次第47页,课件共68页,创作于2023年2月JAVAI/O-文件File类定义了文件系统上的资源。FileaFile=newFile("temp.txt");aFile.exists();//文件是否存在aFile.createNewFile();//如果File不存在,那么可以创建它:第48页,课件共68页,创作于2023年2月流可以使用流访问文件系统上的文件。在最低的级别上,流允许程序接收来自数据源的字节,或者允许将输出发送到目的地。一些流可以处理所有类型的16位字符(类型Reader和Writer)。而其他一些流则只能处理8位字符(类型InputStream和OutputStream)。在这些分层结构中,有几种风格的流(所有流都可以在java.io包中找到)。在最高级别的抽象中,有一些字符流和字节流。第49页,课件共68页,创作于2023年2月流第50页,课件共68页,创作于2023年2月字节流字节流读取(InputStream及其子类)并编写(OutputStream及其子类)8位字节。换句话说,可以将字节流看作是一种更原始的流。因此,也就不难理解为什么关于基本Java语言类的J教程说字节流通常用于二进制数据,比如说图像。以下是一个选定的字节流列表:

FileInputStream

FileOutputStream

从某一文件中读取文件,以及将字节写入某个文件中。

ByteArrayInputStream

ByteArrayOutputStream 从某个内存数组中读取字节,以及将字节写入某个内存数组中。第51页,课件共68页,创作于2023年2月字符流字符流可以读取(Reader及其子类)和写入(Writer及其子类)16位的字符。子类也可以从数据接收器中读取或写入数据,或者处理转换中的字节。以下是一个选定的字符流列表: StringReader

StringWriter 这些流从内存中的String中读取或写入字符。

InputStreamReader

InputStreamWriter(及其子类FileReaderFileWriter) 是字节流与字符流之间的桥梁。Reader风格(flavor)从字节流读取字节,并将它们转换成字符。而Writer风格将字符转换成字节,并将它们放在字节流上。

BufferedReader和BufferedWriter 在缓冲数据的同时读取或写入另个流,它使读取或写入操作更加有效。可以用缓冲的流包装另一个流。第52页,课件共68页,创作于2023年2月读取和写入文件

try{ Filesource=newFile("input.txt"); Filesink=newFile("output.txt"); FileInputStreamin=newFileInputStream(source);FileOutputStreamout=newFileOutputStream(sink); intc; while((c=in.read())!=-1) out.write(c); in.close(); out.close();}catch(Exceptione){ e.printStackTrace();}第53页,课件共68页,创作于2023年2月缓冲流–写存在着几种读取和写入File的方法,但是通常,最简便的方法如下所示:1.在File上创建一个FileWriter。2.将FileWriter包装到一个BufferedWriter中。3.只要有必要,可以在BufferedWriter上调用write()来编写File的内容,通常每个行都是以一个行终止符(即\n)结尾的。4.在BufferedWriter上调用flush()来清空它。5.关闭BufferedWriter,如果有必要,还需要清除它。

代码示例: try{ FileWriterwriter=newFileWriter(aFile); BufferedWriter buffered=newBufferedWriter(writer); buffered.write("Alineoftext.\n"); buffered.flush(); }catch(IOExceptione1){ e1.printStackTrace(); }第54页,课件共68页,创作于2023年2月缓冲流–读Stringline=null;StringBufferlines=newStringBuffer();try{ FileReaderreader=newFileReader(aFile);BufferedReaderbufferedReader=newBufferedReader(reader); while((line=bufferedReader.readLine())!=null){ lines.append(line); lines.append("\n"); }}catch(IOExceptione1){ e1.printStackTrace();}System.out.println(lines.toString());第55页,课件共68页,创作于2023年2月正则表达式正责表达式实质上是一个模式,用于描述共享该模式的一组字符串。例如,以下是一组包含一些常见事物的字符串:astringalongerstringamuchlongerstring这些字符串中的每个字符串都是以“a”开头并以“string”结尾。Stringinput="one,,two,threefour,five";String[]result=input.split("[,\\s]+");for(inti=0;i<result.length;i++){System.out.println(result[i]);}第56页,课件共68页,创作于2023年2月正则表达式Java语言的regex功能有三个核心类:Pattern,描述了一个字符串模式。Matcher,测试字符串,查看它是否与模式匹配。PatternSyntaxException。java.lang.Object

java.util.regex.Matcher(implements java.util.regex.MatchResult)java.util.regex.Pattern(implementsjava.io.Serializable)第57页,课件共68页,创作于2023年2月正则表达式-语法模式语法regex模式描述了表达式试图在输入字符串中查找的字符串的结构。 构造 什么才是合格的匹配

. 任何字符

? 以前的零(0)或壹(1)。

* 以前的零(0)或其他数字。

+ 以前的壹(1)或其他数字。

[] 字符或数字的范围。

^ 否定情况(也就是说,“不是<凡是…>”)。

\d 任何数字(可以用[0-9]替换)。

\D 任何非数字(可以用[^0-9]替换)。

\s 任何空白字符(可以用[\n\t\f\r]替换)。

\S 任何非空白字符(可以用[^\n\t\f\r]替换)。

\w 任何单词字符(可以用[a-zA-Z_0-9]替换)。

\W 任何非单词字符(可以用[^\w]替换)。

第58页,课件共68页,创作于2023年2月Pattern类-方法staticPatterncompile(Stringregex)将给定的正则表达式编译并赋予给Pattern类Matchermatcher(CharSequenceinput)生成一个给定命名的Matcher对象String[]split(CharSequenceinput)将目标字符串按照Pattern里所包含的正则表达式为模进行分割.String[]split(CharSequenceinput,intlimit)作用同上,增加参数limit目的在于要指定分割的段数,如将limi设为2,那么目标字符串将根据正则表达式分为割为两段.

第59页,课件共68页,创作于2023年2月Pattern类-示例Stringinput="Kevinhasseen《LEON》sevealtimes,becauseitisagoodfilm."+"/凯文已经看过《这个杀手不太冷》几次了,因为它是一部"+"好电影。/名词:凯文。";Patternp=Ppile("[/]+");String[]result=p.split(input);//p.split(input,3)for(inti=0;i<result.length;i++){System.out.println(result[i]);}输出:Kevinhasseen《LEON》sevealtimes,becauseitisagoodfilm.凯文已经看过《这个杀手不太冷》几次了,因为它是一部好电影。名词:凯文。

第60页,课件共68页,创作于2023年2月Pattern类-示例Patternp=Ppile("[/]+");String[]result=p.split("Kevinhasseen《LEON》sevealtimes,becauseitisagoodfilm."+"/凯文已经看过《这个杀手不太冷》几次了,因为它是一部"+"好电影。/名词:凯文。“,2);for(inti=0;i<result.length;i++){ System.out.println(result[i]);}输出:Kevinhasseen《LEON》sevealtimes,becauseitisagoodfilm.凯文已经看过《这个杀手不太冷》几次了,因为它是一部好电影。/名词:凯文。第61页,课件共68页,创作于2023年2月正则表达式-匹配//字符串以‘a’开头,然后是零个或多个字符,最后以‘string’结尾

Patternpattern=Ppile(“a.*string”);Matchermatcher=pattern.matcher("astring");booleandidMatch=matcher.matches();System.out.println("是否匹配:"+didMatch);intpatternStartIndex=matcher.start();System.out.println("起始索引值:"+patternStartIndex);intpatternEndIndex=matcher.end();System.out.println("终止索引值:"+patternEndIndex);输出:是否匹配:true起始索引值:0终止索引值:8matches()只告诉我们整个输入顺序是否与模式严格匹配。start()告诉我们所匹配字符串起始的那个字符串中的索引值。end()告诉我们所匹配字符串终止的那个字符串中的索引值,并用该值减去1。

第62页,课件共68页,创作于2023年2月Matcher类–方法StringreplaceAll(Stringreplacement)

将目标字符串里与既有模式相匹配的子串全部替换为指定的字符串。

StringreplaceFirst(Stringreplacement)

将目标字符串里第一个与既有模式相匹配的子串替换为指定的字符串。MatcherappendReplacement(StringBuffersb,Stringreplacement)

将当前匹配子串替换为指定字符串,并且将替换后的子串以及其之前到上次匹配子串之后的字符串段添加到一个StringBuffer对象。StringBufferappendTail(StringBuffersb)

将最后一次匹配工作后剩余的字符串添加到一个StringBuffer对象里。booleanfind()

尝试在目标字符串里查找下一个匹配子串。booleanlookingAt()

检测目标字符串是否以匹配的子串起始。booleanmatches()

尝试对整个目标字符展开匹配检测,也就是只有整个目标字符串完全匹配时才返回真值。

第63页,课件共68页,创作于2023年2月Matcher类-示例Stringinput="HereisaWikiWordfollowedbyAnotherWikiWord,thenSomeWikiWord.";Patternpattern=Ppile("[A-Z][a-z]*([A-Z][a-z]*)+");Matchermatcher=pattern.matcher(input);StringBufferbuffer=newStringBuffer();while(matcher.find()){matcher.appendReplacement(buffer,"blah$0blah");//matcher.group(0)System.out.println("匹配后的内容为:"+buffer);}matcher.appendTail(buffer);System.out.println("After:"+buffer.toString());输出:匹配后的内容为:HereisablahWikiWordblah匹配后的内容为:HereisablahWikiWordblahfollowedbyblahAnotherWikiWordblah匹配后

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论