﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-CreJavasky-文章分类-java技术</title><link>http://www.blogjava.net/CreJavasky/category/12491.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 01 Mar 2007 01:39:01 GMT</lastBuildDate><pubDate>Thu, 01 Mar 2007 01:39:01 GMT</pubDate><ttl>60</ttl><item><title>垃圾收集机制的基本原理及方法</title><link>http://www.blogjava.net/CreJavasky/articles/88014.html</link><dc:creator>小桥 流水</dc:creator><author>小桥 流水</author><pubDate>Fri, 15 Dec 2006 09:48:00 GMT</pubDate><guid>http://www.blogjava.net/CreJavasky/articles/88014.html</guid><wfw:comment>http://www.blogjava.net/CreJavasky/comments/88014.html</wfw:comment><comments>http://www.blogjava.net/CreJavasky/articles/88014.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/CreJavasky/comments/commentRss/88014.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/CreJavasky/services/trackbacks/88014.html</trackback:ping><description><![CDATA[
		<strong>2．1 JVM中内存的划分</strong>
		<p>
		</p>
		<p>
				<strong>
				</strong>
		</p>
		<div id="8">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">　　</span>垃圾收集器对Java程序员来说，基本上是透明的，但是只有了解GC的工作原理、如何优化GC的性能、如何与GC进行有限的交互，才能提高整个应用程序的性能、全面提升内存的管理效率,为了说明其工作方式，我们首先看看内存中几种常用的存放数据的地方：</div>
		<p>
		</p>
		<p>
		</p>
		<div id="9">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">　　</span>(1) 堆栈（Stack）：位于常规RAM（随机访问存储器）区域，但可通过它的“堆栈指针”获得处理器的直接支持。堆栈指针若向下移，会创建新的内存；若向上移，则会释放那些内存。这是一种特别快、特别有效的数据保存方式，仅次于CPU的寄存器。创建程序时，Java编译器必须准确地知道堆栈内保存的所有数据的“长度”以及“存在时间”。这是由于它必须生成相应的代码，以便向上和向下移动指针。这一限制无疑影响了程序的灵活性，所以尽管有些Java数据要保存在堆栈里--特别是对象的引用（也可称为对象的引用变量），但Java中的对象不会放在其中。 </div>
		<p>
		</p>
		<p>
		</p>
		<div id="10">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">　　</span>(2) 堆（Heap）。一种常规用途的内存池（也在RAM区域），其中保存了Java对象。和堆栈不同，“内存堆”或“堆”（Heap）最吸引人的地方在于编译器不必知道要从堆里分配多少存储空间，也不必知道存储的数据要在堆里停留多长的时间。因此，用堆保存数据时会得到更大的灵活性。要求创建一个对象时，只需用new命令编制相关的代码即可。执行这些代码时，会在堆里自动进行数据的保存。当然，为达到这种灵活性，必然会付出一定的代价：在堆里分配存储空间时会花掉更长的时间！这是导致Java性能不佳的因素之一。 </div>
		<p>
		</p>
		<p>
		</p>
		<div id="11">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">　　</span>SUN的JVM使用分代方式（Generation）管理堆空间，“代”分配给新旧对象的内存池。这些对象的不断积累会导致一个的内存状态，从而推动垃圾收集的开始。如图说明了SUN的JVM中堆空间粗略的划分。 </div>
		<p>
		</p>
		<p>
		</p>
		<div id="12">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">　　</span>年轻的一代包括年轻的对象空间（eden）和两个存活（survivor）空间（SS#1和SS#2）。新对象被分配到eden中，那些存活较久的对象则会从年轻的一代转移到老一代中。图中的Perm段叫做永久代（permanent generation），它保存了JVM的类和方法对象。 </div>
		<p>
		</p>
		<p>
		</p>
		<div id="13">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">　　</span>(3) 静态存储（Static）。这儿的“静态”（Static）是指“位于固定位置”（尽管也在RAM里）或是有且仅有一份。程序运行期间，静态存储的数据将随时等候调用。可用static关键字指出一个对象的特定元素是静态的。但Java对象本身永远都不会置入静态存储空间。 </div>
		<p>
		</p>
		<p>
		</p>
		<div id="14">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">　　</span>
				<strong>2．2 对象在内存中的分配  </strong>
		</div>
		<p>
		</p>
		<p>
		</p>
		<div id="15">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">　　</span>了解了内存中这些存放数据的方式后，我们先来看看C++中存放对象的机制：在C++中，对象可以是在堆栈中创建的，这样可达到更快的速度。然而，在C++里创建“内存堆”（Heap）对象通常会慢得多。这种内存堆实际是一个大的内存池，要求必须进行再循环（再生）。这里可以把C++的Heap想象是一块场地，在这里面中每个对象不断监视属于自己的地盘，他们可能在以后的某个时刻不再继续占用目前所占用的空间，即释放后的内存会在堆里留下一个洞，所以再调用new的时候，存储分配机制必须进行某种形式的搜索，使新对象能够利用已经存在的空洞，否则就会很快用光堆的存储空间。之所以内存堆的分配会在C++里对性能造成如此重大的性能影响，对可用内存的搜索正是一个重要的原因。所以创建基于堆栈的对象要快得多。 </div>
		<p>
		</p>
		<p>
		</p>
		<div id="16">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">　　</span>而在Java中的内存堆（Heap）更像一条传送带：每次分配了一个新对象后，“Heap指针”都会朝前移动，这意味着对象存储空间的分配可以达到非常快的速度。因为“Heap指针”只是单纯的往前移动至未经分配的区域，所以它与C++的堆栈分配方式几乎是不相上下的（当然，在数据记录上会多花一些开销，但要比搜索存储空间快多了）。但是如果只是按那种方式分配，最终就要求进行大量的内存页面交换（这对性能的发挥会产生巨大干扰），而且终究会用光内存，出现内存分页错误（page fault）。所以Java引入了“垃圾收集器”。它在收集“垃圾”的同时，也负责重新紧密排列（compact）堆里的所有对象，消除内存空洞，将“堆指针”移至尽可能靠近传送带开头的地方，远离发生（内存）分页错误的地点。垃圾收集器会重新安排所有东西，使其成为一个高速、无限自由的堆模型，同时游刃有余地分配存储空间。但是垃圾收集时的代价是非常高昂的，这也是导致Java性能不佳的因素之一。<br /><br /></div>
<img src ="http://www.blogjava.net/CreJavasky/aggbug/88014.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/CreJavasky/" target="_blank">小桥 流水</a> 2006-12-15 17:48 <a href="http://www.blogjava.net/CreJavasky/articles/88014.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转： Java 容器</title><link>http://www.blogjava.net/CreJavasky/articles/87959.html</link><dc:creator>小桥 流水</dc:creator><author>小桥 流水</author><pubDate>Fri, 15 Dec 2006 07:40:00 GMT</pubDate><guid>http://www.blogjava.net/CreJavasky/articles/87959.html</guid><wfw:comment>http://www.blogjava.net/CreJavasky/comments/87959.html</wfw:comment><comments>http://www.blogjava.net/CreJavasky/articles/87959.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/CreJavasky/comments/commentRss/87959.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/CreJavasky/services/trackbacks/87959.html</trackback:ping><description><![CDATA[转：Java中容器是Java3中比较方便快捷的容器，在各种程序中运用的比较多，给我们的编程带来了很大的方便。 
<div><span style="FONT-SIZE: 10pt">　　</span>Array的长度是固定的且无法动态改变其长度，也就是说定义大小后，此变量的大小不可以再改变了，但它是最有效的一个容器，存取速度相当快。</div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>Array对象用length成员进行计算元素个数，通过[]来取用数据，array对象无法判断元素个数，只能计算其容量。</div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>Array类拥有一组static函数，equals(),fill(),sort(),binary(),</div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>Array复制System.arrayCopy().</div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>compareTo()接受一个对象引数，此引数大于自己时返回负值，相等时返回零，小于时返回正值。</div><div> </div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>Java中的最关键的三个容器接口（list,set,map）.</div><div> </div><div><strong><span style="FONT-SIZE: 10pt">　　</span>List</strong><strong>是一个interface</strong></div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>List以元素按插次序来放置元素，不会重新排列。</div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>ArrayList以Array实现完成的List，允许快速随机访问。如果只是简单地存取数据，而不对其中的数据进行有序插入使用此容器会很方便且速度很快。LinkList提供最佳循序访问，具有addFirst(),addLast(),getFirst(),getLast(),removeFirst(),removeLast()，如果需要在队列中插入一些数据，可用此容器。由于其list的灵活性，在各种程序中使用的比较多。</div><div> </div><div> </div><div><strong><span style="FONT-SIZE: 10pt">　　</span>Set</strong><strong>就是一个Collection </strong><strong>不接受重复元素，它使用自己内部的一个排列机制。</strong></div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>Set拥有和Collection一样的interfaces</div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>HashSet注重查找时间，所有元素必须定义hashCode();对自己中的数据不进行有序排列，按照加入的先后次序进行排列。</div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>TreeSet底层结构为tree的一种有序Set. 内部数据进行有序排列。</div><div> </div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>Map也不接受重复元素，重复与否以键值（key）判断，它拥有自己的内部排列机制。</div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>ArrayList使用数字来选择值，而Map使用另一个对象来取值。</div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>Map用put将Value值加入，用get()传回key对应的value。</div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>使用containsKey()和containsValue()来检查map内是否含有某个key或某个value。</div><div><br /> </div><div><strong><span style="FONT-SIZE: 10pt">　　</span>Map</strong><strong>包括两个maps</strong><strong>，HashMap,TreeMap</strong></div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>HashMap会运用对象的hashCode()并利用它来快速找到key，带来巨幅的效率提升。HashMap取代了Java2中的HashTable容器。</div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>TreeMap基于红黑树完成的一个实现品，它的数据按次序排列并惟一拥有subMap(),此函数返回tree中的部分组成。</div><div> </div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span><strong>容器的填充</strong></div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>ArrayList以 add()方法进行数据的增加。容器有个Collections Class，含有一些static函数，比如fill()，它将用一个object reference 复制到容器的每个位置上（只能list有用）,即把原先的值覆盖掉，此函数用处不大。</div><div> </div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span><strong>迭代器Iterator</strong></div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>迭代器是个对象，其职责便是走访以及选择序列中的一连串对象，迭代器是“轻量级”对晚，产生的代价极小。</div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>第一次调用Iterator的next()时，返回序列中的第一个元素。</div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>调用next()取得序列中的下一个元素。</div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>调用hasNext()检查序列是否还有其它元素。</div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>调用remove()移去迭代器最新传回的元素。</div><div> </div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span><strong>外引：</strong></div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>C++中的vector容器知道他所持有的对象隶属型别，但不进行边界检查，而Java中的容器都进行了边界检查，一旦越界即报RuntimeException。边界检查会带来额外的效率负担。</div><div> </div><div><span style="FONT-SIZE: 10pt">　　</span>Java中的容器可以持有Java任何对象（基本型别除外）。 一旦将对象装入容器，其型别就会丢失，当你使用的时候，必须先进行转型。</div><img src ="http://www.blogjava.net/CreJavasky/aggbug/87959.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/CreJavasky/" target="_blank">小桥 流水</a> 2006-12-15 15:40 <a href="http://www.blogjava.net/CreJavasky/articles/87959.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>