欢迎来到天天文库
浏览记录
ID:20673160
大小:38.50 KB
页数:10页
时间:2018-10-14
《破除java神话》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、破除java神话之一:垃圾收集解决所有的内存问题破除java神话之二:参数是传址的破除java神话之三:原子操作都是线程安全的破除java神话之四:同步代码等同于断面(criticalsection)破除java神话之一:垃圾收集解决所有的内存问题对于java程序员而言,垃圾收集功能是一个非常大的帮助,同时也是使用java语言的一个非常大的优势。然而,实际情况应该是不能因为垃圾收集可以清除无用的内存就不去考虑内存问题。这里要指明的是,如果忽略这个问题,那么就会导致问题。首先,在不同的JVM上垃圾收集算法是不同的,因此,如果你想你的程序能够很好的运行在不
2、同的JVM上,那么就不能依赖垃圾收集的特定行为。垃圾收集是一个非常活跃的研究问题,更好、更快并且更精确的收集器总在实现中。然而很多现代的垃圾收集器都有着同样的问题。其中一个是当他们运行时并非总是释放所有那些可以被收集的对象。分析表明java编程中大多对象的生存期是短暂的,因此,对于需要提高性能的收集器而言,他们会减少检查那些具有较长生命的对象的频度,这个是依据大多对象具有较短的生存期,而那些生存期较长的对象往往会被继续引用,因此,没有必要在每次检查时都去检查这样的对象是否可以被回收。要释放特定的对象的内存可能需要多次调用垃圾收集。你可以通过调用Syst
3、em.gc方法建议(注意是建议)垃圾收集器运行。请求这个方法的结果通常导致垃圾收集器进行一次完整的收集。通常这个比VM调用垃圾收集要更彻底和完全,也会尽可能快的完成。如果程序员显式的调用System.gc,那么推论是有更多的时间做更多的工作(请注意是有更多的事情做更多的事情,这意味着将进行大量的检查,还记得刚才的有关对长短生命期对象的检查的频度的变化吗?而不是真正彻底的清除)。在任何一种情况下(显式调用垃圾收集和VM调用垃圾收集)都不要假设所有可以被收集的对象会真正的被收集。显式的调用System.gc有更大的机会完成彻底的收集,但不是保证会完成。另一
4、个程序员会遇到的麻烦是他们往往保持对那些不再需要的对象的引用。这将阻止垃圾收集器释放该对象。这种情况在你自己管理列表的时候会发生。考虑下面的ObjStack类。这个类使用push和pop方法管理堆栈中的对象。两个方法都利用索引,该索引指明堆栈中下一个可用的位置。push方法存储对新对象的引用并增加索引值,而pop方法减小索引值并返回堆栈最上面的元素。实例一:没有正确实现pop方法的ObjStackclassObjStack{privateObject[]stack;privateintindex;publicvoidpush(Objecto){stac
5、k[index]=o;index++;}publicObjectpop(){index-;returnstack[index];}//...}现在创建一个容量为10的对象,然后调用8次push方法向它添加对象,那么此时索引值为8。现在考虑三次调用pop方法后发生什么?此时的索引值为5,但是请注意,除了这个索引值发生变化外堆栈其实没有其它任何变化!虽然pop方法减小了索引值,但是实际上堆栈仍然保持着对那些对象的引用。调用pop方法往往意味着那些对象应该被收集(大多情况是如此的,即使不是马上,也是在稍后使用完该对象后)。然而由于堆栈仍然保留有对该对象的引用
6、,它就不能被收集。这些对象只能在调用push后被替换才可能被收集。正确的pop的实现如下:publicObjectpop(){index-;Objecto=stack[index];stack[index]=null;returno;}在这个版本的pop方法中,当引用被返回后,堆栈删除对他们的引用因此垃圾收集器在以后可以回收他们。在你自己的编码中,对于那些不需要的对象,不要在引用它们!程序的执行极大收到可用内存的影响,可用内存越少,那么垃圾收集的执行次数越多,这将极大的伤害性能。破除java神话之二:参数是传址的在不同的java新闻组中,参数是传值还是
7、传址一直是一个经常被争辩的话题。误解的中心是以下两个事实:1、对象是传引用的2、参数是传值的这两个能够同时成立吗?一个字:是!在java中,你从来没有传递对象,你传递的仅仅是对象的引用!一句话,java是传引用的。然而,当你传递一个参数,那么只有一种参数传递机制:传值!通常,当程序员讨论传值和传引用时,他们是指语言的参数传递机制,c++同时支持这两种机制,因此,以前使用过c++的程序员开始好像不能确定的java是如何传参数的。java语言为了事情变得简单只支持参数传值的机制。java中的变量有两种类型:引用类型和原始类型。当他们被作为参数传递给方法时,
8、他们都是传值的。这是一个非常重要的差别,下面的代码范例将说明这一点。在继续前,我们有必要定义一
此文档下载收益归作者所有