对象引用与垃圾收集.ppt

上传人:牧羊曲112 文档编号:6224944 上传时间:2023-10-07 格式:PPT 页数:68 大小:226KB
返回 下载 相关 举报
对象引用与垃圾收集.ppt_第1页
第1页 / 共68页
对象引用与垃圾收集.ppt_第2页
第2页 / 共68页
对象引用与垃圾收集.ppt_第3页
第3页 / 共68页
对象引用与垃圾收集.ppt_第4页
第4页 / 共68页
对象引用与垃圾收集.ppt_第5页
第5页 / 共68页
点击查看更多>>
资源描述

《对象引用与垃圾收集.ppt》由会员分享,可在线阅读,更多相关《对象引用与垃圾收集.ppt(68页珍藏版)》请在三一办公上搜索。

1、J2SE,1.4,Tigerflower 2005-1,主题,对象引用与垃圾收集异常处理JAVA I/O正则表达式利用JAVA进行XML编程嵌套式类对象的封装与继承抽象类与接口,垃圾收集,垃圾收集器的工作原理是识别程序中不再使用的对象,并且回收其内存。,垃圾收集,J2SE1.4采用的代间收集策略,垃圾收集,JDK1.4的垃圾收集器 复制收集器、标记整理收集器、增量式收集器、并行复制收集器、并行清除(scavenging)收集器和并发标记-清除收集器。,垃圾收集,其他收集选项,垃圾收集,观察垃圾收集运行状况有很多办法来监听垃圾回收器的活动。可用Xverbose:gc选项运行JVM,然后观察输出结

2、果一段时间。memory 13.009-13.130:GC 65536K-16788K(65536K),121.000 ms,垃圾收集,微调垃圾收集选项最简单的垃圾收集微调就是扩大最大堆的大小(-Xmx)。随着堆的增大,复制收集会变得更有效,所以在增大堆时,您就减少了每个对象的收集成本。除了增加最大堆的大小,还可以用选项-XX:NewRatio 增加分配给年轻代的空间份额。也可以用-Xmn 选项显式指定年轻代的大小。,引用对象,从JDK1.2开引入了一个引用对象应用程序接口API允许程序维持一个特别的到对象的引用,这样程序能够通过这一有限的途径和垃圾收集器进行交互。加入引用对象之后的引用与常规

3、引用的区别在于,引用对象中的引用专门由内存管理器来处理。引用对象封装了其它一些对象的引用,我们称之为指示对象。在引用对象创建的同时,也就定义了该引用对象的指示对象。,Heap中的引用对象Reference Objects,Reference Objects 类层次,对象的引用层次,根据对象的可获取程度:强获取、次获取、弱获取、虚获取根据应用程序要求,对象可以是强引用(strong references)、次引用(soft references)、弱引用(weak references)、虚引用(phantom references)的任意组合。,强引用(strong reference),JV

4、M内存管理器从引用集合出发遍寻堆中所有到对象的路径。当到达某对象的任意路径都不含有引用对象时,则称该对象具有强获取能力。该对象为强引用对象,Root set of references,strong references,garbage,次引用(soft reference),次引用(soft reference),public class DisplayImage extends Applet SoftReference sr=null;public void init()System.out.println(Initializing);public void paint(Graphics

5、g)Image im=(sr=null)?null:(Image)(sr.get();if(im=null)System.out.println(Fetching image);im=getImage(getCodeBase(),truck1.gif);sr=new SoftReference(im);System.out.println(Painting);g.drawImage(im,25,25,this);im=null;public void start()public void stop();,次引用(Soft Reference),所有Soft Reference到的对象保证会在j

6、ava虚拟机发生OutOfMemoryError 前被清除。SoftReference 常被用来实现 object-cache(memory-sensitive caches)之用的。被 Soft Reference 指到的对象,即使没有任何 Direct Reference,也不会被清除。一直要到 JVM 内存不足时且 没有 Direct Reference 时才会清除,如此一来 SoftReference 不但可以把对象 cache 起来,也不会造成内存不足的错误(OutOfMemoryError)。,弱引用(weak reference),当内存管理器未发现strong referenc

7、es 和 soft references 时,我们称对象具有弱获取能力,即在到达该对象的路径中至少包含一个weak reference。,弱引用(weak reference),弱引用(weak references)允许用来查询一个对象是否已被垃圾收集器回收。Image im=(sr=null)?null:(Image)(sr.get();if(im=null)System.out.println(Fetching image);im=getImage(getCodeBase(),truck1.gif);sr=new SoftReference(im);,public class WeakO

8、bj public static void main(String args)try ReferenceQueue aReferenceQueue=new ReferenceQueue();Object anObject=new Object();WeakReference ref=new WeakReference(anObject,aReferenceQueue);String extraData=new String(Extra Data);HashMap aHashMap=new HashMap();aHashMap.put(ref,extraData);/(key)in aHashM

9、ap anObject=null;if(anObject=null)/Clear the strong reference to extraData extraData=null;catch(Exception e)System.err.println(An exception occurred:);e.printStackTrace();,weak reference 分析,Soft Reference 和 Weak Reference 的不同在于前者是否会收集是由垃圾收集器的算法决定的,而后者是一定会被收集的。,虚引用(Phantom Reference),主要是用来取代对象的 final

10、ize()和 Weak Reference 以 及 SoftReference 最大的不同是:Phantom Reference 一订要搭配着 ReferenceQueue 使用,因为 Phantom Reference 的 get()传 出值一定是 null(以避免此对象不小心再度拥有 Direct Reference)。,Java对象引用接口应用,1.基于Web的应用程序常常要求显示大量图片,当用户离开某一Web页时,往往不能确定是否能够顺利的返回。在这种程序中,应用Java对象引用API可以创建这样一个环境,即当堆内存以最小程度运行时,内存管理器创建对象。当用户返回时,应用程序就会重新载

11、入已经创建的图片。,Java对象引用接口应用,2.应用对象引用队列可以创建这样一个环境,当通过对象引用获得某一对象时,应用程序得到通知。然后,应用程序就可以对相关对象进行清除操作,同时使这些对象在内存管理器中合法化。,内存泄漏,内存泄露的本质是无用但仍被引用的对象。仅当一个对象不再被引用时才能被统计为无用的对象。垃圾收集器只能收集没有被应用程序引用的对象。,无用但仍被引用的对象,上面说明了在 Java 应用程序执行期间具有不同生存周期的两个类。类 A 首先被实例化,并会在很长一段时间或程序的整个生存期内存在。在某个时候,类 B 被创建,类 A 添加对这个新创建的类的一个引用。现在,我们假定类

12、B 是某个用户界面小部件,它由用户显示甚至解除。如果没有清除类 A 对 B 的引用,则即便不再需要类 B,并且即便在执行下一个垃圾收集周期以后,类 B 仍将存在并占用内存空间。,内存泄漏无意识的对象保留,public class Stack private Object elements;private int size=0;public Stack(int initialCapacity)this.elements=new ObjectinitialCapacity;public void push(Object e)ensureCapacity();elementssize+=e;publ

13、ic Object pop()if(size=0)throw new EmptyStackException();Object result=elements-size;return result;private void ensureCapacity()if(elements.length=size)Object oldElements=elements;elements=new Object2*elements.length+1;System.arraycopy(oldElements,0,elements,0,size);,内存泄漏错误的局部作用域,static StringBuffer

14、 sb=new StringBuffer();public static String scopingExample(String string)sb=new StringBuffer();sb.append(hello).append(string);sb.append(,nice to see you!);return sb.toString();,资源泄漏,释放资源有一个简单的原则:如果有资源清理方法(colse、free)就及时调用。使用finally 避免资源泄漏(resource leaks)finally构件使得某些代码总是得以被执行,无论是否发生异常。在维护对象内部状态和清理n

15、on-memory 资源方面,finally 尤其适用。,资源泄漏被放弃的JDBC对象,Connection conn=null;try conn=getConnection();for(int i=0;i NUM_T;i+)Statement stmt=null;ResultSet rs=null;stmt=conn.createStatement();rs=stmt.executeQuery(/*some query*/);catch(SQLException e)/handle any exceptions finally try if(conn!=null)conn.close();c

16、atch(SQLException ignor),显示关闭资源,在 finally 块中显式关闭 Connection、Statement 和 ResultSet对象,以确保无论是在正常还是异常情况下都将所有 JDBC 对象关闭。try conn=JNDIUtils.getConnection(DS_NAME);st=con.createStatement();rs=st.executeQuery(query);/对结果集操 catch(Exception e)/handle exception finally DbUtils.close(rs);DbUtils.close(st);DbUti

17、ls.close(conn);,J2EE容器中的连接池,尽管根据 JDBC 规范的规定,关闭Connection 时正常情况下也会将 Statement 和 ResultSet 关闭,但不同的提供者都有具体的实现。建议用过资源要及时释放,避免对pool实现的依赖。特别地对于connection执行close时只是将该连接返还给连接池而已。,异常处理异常的继承构架,Throwable Error(严重的系统错误)LinkageError ThreadDeath VirtualMachineError.Exception ClassNotFoundException CloneNotSupport

18、edException IllegalAccessException.RuntimeException(执行期异常)ArithmeticException ArrayStoreException ClassCastException,异常处理,1.可以被抛出。2.可以被捕获。3.可以被程序化地创建。4.可以被 JVM 创建。5.被表示为第一级对象。6.继承的深度从 3 开始。7.由 String(和来自 1.4 的 StackTraceElement s)组成。8.依靠本机方法 fillInStackTrace()。,异常处理,异常处理的原则必须对异常有所作为当异常(exception)诞生时

19、,如果你不捉(catch)它,会发生什么事呢?在Java中如果异常产生了却未被捕获,发生异常的那个线程(thread)将因而中断。所以你必须对你的代码所产生的异常有所作为。,异常处理,对异常的可作为方式:1.捕捉并处理它,防止它进步传播(propagate)。2.捕捉并再次抛出它,这么来它会被传播给调用端。3.捕捉它,然后抛出个新异常给调用端。4.不捕捉这个异常,听任它传播给调用端。,异常处理千万不要遮掩异常,public void m1()/.try/Code that could throw a FileNotFoundExceptioncatch(FileNotFoundExceptio

20、n fnfe)/The exception stops here/.Rest of code in method,异常处理避免极度通用的处理方式,意外地淹没 RuntimeExceptiontry doSomething();catch(Exception e)log(e);,异常处理理解throws 子句,提供throws 子句的用意在于,提醒函数调用者,告知可能发生的异常。当你给出throws 子句的时候,要填写得完整无缺。虽然编译器不强求这样,但将函数可能抛出的所有异常统统列出,是良好的编程习惯。,异常处理不完整的throws 子句,不完整的throws子句使调用者对真实的异常变得难于处

21、理class Exception1 extends Exception class Exception2 extends Exception1 class Exception3 extends Exception2 class Lazypublic void foo(int i)throws Exception1if(i=1)throw new Exception1();if(i=2)throw new Exception2();if(i=3)throw new Exception3();,异常处理 Try区段的一个陷阱,最好不要在catch块中返回值class FinallyTestpubl

22、ic int method1()try return 2;catch(Exception e)return 3;public int method2()try return 3;finally return 4;,异常处理不要将异常用于流程控制,将异常用于流程控制会使程序性能低下、含义模糊,难以维护class DoneWithLoopException extends Exceptionclass Testpublic void foo()/.try while(true)/Do something.if(some loop terminating condition)throw new Do

23、neWithLoopException();catch(DoneWithLoopException e)/.,异常处理不要滥用异常,不要针对所有情形使用异常,应该将异常用于符合其意义的地方 int data;MyInputStream in=new MyInputStream(filename.ext);data=in.getData();while(data!=0)/Do something with datadata=in.getData();,异常处理不要滥用异常,应该是面对不可预料的行为,才使用异常。int data;MyInputStream in=new MyInputStream

24、(filename.ext);try while(true)data=in.getData();/Do something with datacatch(NoMoreDataException e1),异常处理关于检查型异常和非检查型异常,检查型异常代表关于一个合法指定的请求的操作的有用信息,调用者可能已经对该操作没有控制,并且调用者需要得到有关的通知 例如,文件系统已满,或者远端已经关闭连接,或者访问权限不允许该动作。,异常处理关于检查型异常和非检查型异常,对于因为编程错误而导致的异常,或者是不能期望程序捕获的异常(解除引用一个空指针,数组越界,除零,等等),为了使开发人员免于处理这些异常,

25、一些异常被命名为非检查型异常(即那些继承自 RuntimeException 的异常)并且不需要进行声明。,JAVA I/O,Java 语言程序使用的数据必须来自某个地方。通常,这些数据来自一些外部数据源。有许多不同种类的数据源,其中包括数据库、套接字上的直接字节转换和文件等。Java 语言提供了许多可以用来从外部数据源获得信息的工具。这些工具大部分都在 java.io 包中。,JAVA I/O,继承层次,JAVA I/O-文件,File 类定义了文件系统上的资源。File aFile=new File(temp.txt);aFile.exists();/文件是否存在aFile.createN

26、ewFile();/如果 File 不存在,那么可以创建它:,流,可以使用流 访问文件系统上的文件。在最低的级别上,流允许程序接收来自数据源的字节,或者允许将输出发送到目的地。一些流可以处理所有类型的 16 位字符(类型 Reader 和 Writer)。而其他一些流则只能处理 8 位字符(类型 InputStream 和 OutputStream)。在这些分层结构中,有几种风格的流(所有流都可以在 java.io 包中找到)。在最高级别的抽象中,有一些字符流 和字节流。,流,字节流,字节流读取(InputStream 及其子类)并编写(OutputStream 及其子类)8 位字节。换句话说

27、,可以将字节流看作是一种更原始的流。因此,也就不难理解为什么关于基本 Java 语言类的 教程说字节流通常用于二进制数据,比如说图像。以下是一个选定的字节流列表:FileInputStream FileOutputStream 从某一文件中读取文件,以及将字节写入某个文件中。ByteArrayInputStream ByteArrayOutputStream从某个内存数组中读取字节,以及将字节写入某个内存数组中。,字符流,字符流可以读取(Reader 及其子类)和写入(Writer 及其子类)16 位的字符。子类也可以从数据接收器 中读取或写入数据,或者处理转换中的字节。以下是一个选定的字符流

28、列表:StringReader StringWriter这些流从内存中的 String 中读取或写入字符。InputStreamReader InputStreamWriter(及其子类 FileReader FileWriter)是字节流与字符流之间的桥梁。Reader 风格(flavor)从字节流读取字节,并将它们转换成字符。而 Writer 风格将字符转换成字节,并将它们放在字节流上。BufferedReader 和 BufferedWriter在缓冲数据的同时读取或写入另个流,它使读取或写入操作更加有效。可以用缓冲的流包装 另一个流。,读取和写入文件,try File source=n

29、ew File(input.txt);File sink=new File(output.txt);FileInputStream in=new FileInputStream(source);FileOutputStream out=new FileOutputStream(sink);int c;while(c=in.read()!=-1)out.write(c);in.close();out.close();catch(Exception e)e.printStackTrace();,缓冲流 写,存在着几种读取和写入 File 的方法,但是通常,最简便的方法如下所示:1.在 File 上

30、创建一个 FileWriter。2.将 FileWriter 包装到一个 BufferedWriter 中。3.只要有必要,可以在 BufferedWriter 上调用 write()来编写 File 的内容,通常每个行都是以一个行终止符(即 n)结尾的。4.在 BufferedWriter 上调用 flush()来清空它。5.关闭 BufferedWriter,如果有必要,还需要清除它。代码示例:try FileWriter writer=new FileWriter(aFile);BufferedWriter buffered=new BufferedWriter(writer);buff

31、ered.write(A line of text.n);buffered.flush();catch(IOException e1)e1.printStackTrace();,缓冲流 读,String line=null;StringBuffer lines=new StringBuffer();try FileReader reader=new FileReader(aFile);BufferedReader bufferedReader=new BufferedReader(reader);while(line=bufferedReader.readLine()!=null)lines.

32、append(line);lines.append(n);catch(IOException e1)e1.printStackTrace();System.out.println(lines.toString();,正则表达式,正责表达式 实质上是一个模式,用于描述共享该模式的一组字符串。例如,以下是一组包含一些常见事物的字符串:a string a longer string a much longer string 这些字符串中的每个字符串都是以“a”开头并以“string”结尾。String input=one,two,three four,five;String result=inpu

33、t.split(,s+);for(int i=0;iresult.length;i+)System.out.println(resulti);,正则表达式,Java 语言的 regex 功能有三个核心类:Pattern,描述了一个字符串模式。Matcher,测试字符串,查看它是否与模式匹配。PatternSyntaxException。java.lang.Object java.util.regex.Matcher(implements java.util.regex.MatchResult)java.util.regex.Pattern(implements java.io.Serializ

34、able),正则表达式-语法,模式语法 regex 模式 描述了表达式试图在输入字符串中查找的字符串的结构。构造什么才是合格的匹配.任何字符?以前的零(0)或壹(1)。*以前的零(0)或其他数字。+以前的壹(1)或其他数字。字符或数字的范围。否定情况(也就是说,“不是”)。d任何数字(可以用 0-9 替换)。D 任何非数字(可以用 0-9 替换)。s 任何空白字符(可以用 ntfr 替换)。S 任何非空白字符(可以用 ntfr 替换)。w 任何单词字符(可以用 a-zA-Z_0-9 替换)。W任何非单词字符(可以用 w 替换)。,Pattern类-方法,static Pattern compi

35、le(String regex)将给定的正则表达式编译并赋予给Pattern类 Matcher matcher(CharSequence input)生成一个给定命名的Matcher对象String split(CharSequence input)将目标字符串按照Pattern里所包含的正则表达式为模进行分割.String split(CharSequence input,int limit)作用同上,增加参数limit目的在于要指定分割的段数,如将limi设为2,那么目标字符串将根据正则表达式分为割为两段.,Pattern类-示例,String input=Kevin has seenLE

36、ONseveal times,because it is a good film.+/凯文已经看过这个杀手不太冷几次了,因为它是一部+好电影。/名词:凯文。;Pattern p=Ppile(/+);String result=p.split(input);/p.split(input,3)for(int i=0;i result.length;i+)System.out.println(resulti);输出:Kevin has seenLEONseveal times,because it is a good film.凯文已经看过这个杀手不太冷几次了,因为它是一部好电影。名词:凯文。,Pa

37、ttern类-示例,Pattern p=Ppile(/+);String result=p.split(Kevin has seenLEONseveal times,because it is a good film.+/凯文已经看过这个杀手不太冷几次了,因为它是一部+好电影。/名词:凯文。“,2);for(int i=0;i result.length;i+)System.out.println(resulti);输出:Kevin has seenLEONseveal times,because it is a good film.凯文已经看过这个杀手不太冷几次了,因为它是一部好电影。/名词

38、:凯文。,正则表达式匹配,/字符串以a开头,然后是零个或多个字符,最后以string结尾 Pattern pattern=Ppile(“a.*string”);Matcher matcher=pattern.matcher(a string);boolean didMatch=matcher.matches();(是否匹配:+didMatch);int patternStartIndex=matcher.start();(起始索引值:+patternStartIndex);int patternEndIndex=matcher.end();(终止索引值:+patternEndIndex);输出

39、:是否匹配:true起始索引值:0终止索引值:8matches()只告诉我们整个输入顺序是否与模式严格匹配。start()告诉我们所匹配字符串起始的那个字符串中的索引值。end()告诉我们所匹配字符串终止的那个字符串中的索引值,并用该值减去 1。,Matcher类 方法,String replaceAll(String replacement)将目标字符串里与既有模式相匹配的子串全部替换为指定的字符串。String replaceFirst(String replacement)将目标字符串里第一个与既有模式相匹配的子串替换为指定的字符串。Matcher appendReplacement(S

40、tringBuffer sb,String replacement)将当前匹配子串替换为指定字符串,并且将替换后的子串以及其之前到上次匹配子串之后的字符串段添加到一个StringBuffer对象。StringBuffer appendTail(StringBuffer sb)将最后一次匹配工作后剩余的字符串添加到一个StringBuffer对象里。boolean find()尝试在目标字符串里查找下一个匹配子串。boolean lookingAt()检测目标字符串是否以匹配的子串起始。boolean matches()尝试对整个目标字符展开匹配检测,也就是只有整个目标字符串完全匹配时才返回真值

41、。,Matcher类-示例,String input=Here is a WikiWord followed by AnotherWikiWord,then SomeWikiWord.;Pattern pattern=Ppile(A-Za-z*(A-Za-z*)+);Matcher matcher=pattern.matcher(input);StringBuffer buffer=new StringBuffer();while(matcher.find()matcher.appendReplacement(buffer,blah$0blah);/matcher.group(0)(匹配后的内

42、容为:+buffer);matcher.appendTail(buffer);System.out.println(After:+buffer.toString();输出:匹配后的内容为:Here is a blahWikiWordblah匹配后的内容为:Here is a blahWikiWordblah followed by blahAnotherWikiWordblah匹配后的内容为:Here is a blahWikiWordblah followed by blahAnotherWikiWordblah,then blahSomeWikiWordblahAfter:Here is

43、a blahWikiWordblah followed by blahAnotherWikiWordblah,then blahSomeWikiWordblah.,正则表达式-组,在每个模式中,通常通过使用圆括号闭包部分模式来创建组:Pattern p=Ppile(No.)(.);Matcher m=p.matcher(No.1 is first,No.2 is second.);while(m.find()(该次查找获得匹配组的数量为:+m.groupCount()+匹配字串为:+m.group();for(int i=1;i=m.groupCount();i+)(第+i+组的子串内容为:+

44、m.group(i);该次查找获得匹配组的数量为:2 匹配字串为:No.1第1组的子串内容为:No.第2组的子串内容为:1该次查找获得匹配组的数量为:2 匹配字串为:No.2第1组的子串内容为:No.第2组的子串内容为:2,正则表达式-组,可以通过捕获组 来引用匹配项。public void findWikiWord()String input=Here is a WikiWord followed by AnotherWikiWord,then SomeWikiWord.HaHa;Pattern pattern=Ppile(A-Za-z*(A-Za-z*)+);Matcher matcher

45、=pattern.matcher(input);while(matcher.find()System.out.println(Found this wiki word:+matcher.group();输出:Found this wiki word:WikiWordFound this wiki word:AnotherWikiWordFound this wiki word:SomeWikiWordFound this wiki word:HaHa,正则表达式-组,替换字符串例子String input=Here is a WikiWord followed by AnotherWikiWo

46、rd,then SomeWikiWord.;Patternpattern=Ppile(A-Za-z*(A-Za-z*)+);Matcher matcher=pattern.matcher(input);System.out.println(Before:+input);String result=matcher.replaceAll(“blah$0blah”);/matcher.group(0)System.out.println(After:+result);输出:Before:Here is a WikiWord followed by AnotherWikiWord,then SomeWikiWord.After:Here is a blahWikiWordblah followed byblahAnotherWikiWordblah,then blahSomeWikiWordblah.,嵌套式类,1,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号