﻿<?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-阳光咖啡</title><link>http://www.blogjava.net/chhbjh/</link><description>阳光即为SUN,JAVA便为咖啡。我们沐浴着阳光，在浓郁的咖啡香中，品味编程的乐趣!</description><language>zh-cn</language><lastBuildDate>Wed, 29 Apr 2026 16:51:13 GMT</lastBuildDate><pubDate>Wed, 29 Apr 2026 16:51:13 GMT</pubDate><ttl>60</ttl><item><title>memcache的最佳实践方案。</title><link>http://www.blogjava.net/chhbjh/archive/2012/02/21/370472.html</link><dc:creator>阳光咖啡</dc:creator><author>阳光咖啡</author><pubDate>Tue, 21 Feb 2012 14:54:00 GMT</pubDate><guid>http://www.blogjava.net/chhbjh/archive/2012/02/21/370472.html</guid><wfw:comment>http://www.blogjava.net/chhbjh/comments/370472.html</wfw:comment><comments>http://www.blogjava.net/chhbjh/archive/2012/02/21/370472.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/chhbjh/comments/commentRss/370472.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chhbjh/services/trackbacks/370472.html</trackback:ping><description><![CDATA[<p><strong><font size="4">基本问题</font></strong></p> <p><strong>1、memcached的基本设置</strong> <br>1）启动Memcache的服务器端 <br># /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 -p 12000 -c 256 -P /tmp/memcached.pid</p> <p>-d选项是启动一个守护进程， <br>-m是分配给Memcache使用的内存数量，单位是MB，我这里是10MB， <br>-u是运行Memcache的用户，我这里是root， <br>-l是监听的服务器IP地址，如果有多个地址的话，我这里指定了服务器的IP地址192.168.0.200， <br>-p是设置Memcache监听的端口，我这里设置了12000，最好是1024以上的端口， <br>-c选项是最大运行的并发连接数，默认是1024，我这里设置了256，按照你服务器的负载量来设定， <br>-P是设置保存Memcache的pid文件，我这里是保存在 /tmp/memcached.pid，</p> <p>2）如果要结束Memcache进程，执行：</p> <p># kill `cat /tmp/memcached.pid`</p> <p><a href="http://baike.baidu.com/view/273836.htm"><font color="#000000">哈希算法</font></a><font color="#000000">将</font>任意长度的二进制值映射为固定长度的较小二进制值，这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该</p> <p>段落的一个字母，随后的哈希都将产生不同的值。要找到散列为同一个值的两个不同的输入，在计算上是不可能的。</p> <p><strong>2、一致性Hash算法的目的有两点：一是节点变动后其他节点受影响尽可能小；二是节点变动后数据重新分配尽可能均衡 。</strong></p> <p><strong>3、为什么要运行 memcached ？</strong></p> <p>如果网站的高流量很大并且大多数的访问会造成数据库高负荷的状况下，使用 memcached 能够减轻数据库的压力。</p> <p><strong>4、适用memcached的业务场景？</strong></p> <p>1）如果网站包含了访问量很大的动态网页，因而数据库的负载将会很高。由于大部分数据库请求都是读操作，那么memcached可以显著地减小数据库负载。</p> <p>2）如果数据库服务器的负载比较低但CPU使用率很高，这时可以缓存计算好的结果（ computed objects ）和渲染后的网页模板（enderred templates）。</p> <p>3）利用memcached可以缓存<strong>session数据</strong>、临时数据以减少对他们的数据库写操作。</p> <p>4）缓存一些很小但是被频繁访问的文件。</p> <p>5）缓存Web 'services'（非IBM宣扬的Web Services，译者注）或RSS feeds的结果.。</p> <p><strong>5、不适用memcached的业务场景？</strong></p> <p>1）缓存对象的大小大于1MB </p> <p>Memcached本身就不是为了处理庞大的多媒体（large media）和巨大的二进制块（streaming huge blobs）而设计的。 </p> <p>2）key的长度大于250字符 </p> <p>3）虚拟主机不让运行memcached服务 </p> <p>&nbsp;&nbsp;&nbsp;&nbsp; 如果应用本身托管在低端的虚拟私有服务器上，像vmware, xen这类虚拟化技术并不适合运行memcached。Memcached需要接管和控制大块的内存，如果memcached管理的内存</p> <p>被OS或 hypervisor交换出去，memcached的性能将大打折扣。</p> <p>4）应用运行在不安全的环境中 </p> <p>Memcached为提供任何安全策略，仅仅通过telnet就可以访问到memcached。如果应用运行在共享的系统上，需要着重考虑安全问题。</p> <p>5）业务本身需要的是持久化数据或者说需要的应该是database</p> <p><strong>6、能够遍历memcached中所有的item吗？</strong></p> <p>不能，这个操作的速度相对缓慢且阻塞其他的操作（这里的缓慢时相比memcached其他的命令）。memcached所有非调试（non-debug）命令，例如add, set, get, fulsh等无论</p> <p>memcached中存储了多少数据，它们的执行都只消耗常量时间。任何遍历所有item的命令执行所消耗的时间，将随着memcached中数据量的增加而增加。当其他命令因为等待（遍历所</p> <p>有item的命令执行完毕）而不能得到执行，因而阻塞将发生。</p> <p><strong><font size="4">集群的相关问题</font></strong></p> <p><strong>7、memcached是怎么工作的？</strong></p> <p>Memcached的高性能源于两阶段哈希（two-stage hash）结构。Memcached就像一个巨大的、存储了很多&lt;key,value&gt;对的哈希表。通过key，可以存储或查询任意的数据。 客户端</p> <p>可以把数据存储在多台memcached上。当查询数据时，客户端首先参考节点列表计算出key的哈希值（阶段一哈希），进而选中一个节点；客户端将请求发送给选中的节点，然后</p> <p>memcached节点通过一个内部的哈希算法（阶段二哈希），查找真正的数据（item）并返回给客户端。从实现的角度看，memcached是一个非阻塞的、基于事件的服务器程序。</p> <p><strong>8、memcached最大的优势是什么？</strong></p> <p>Memcached最大的好处就是它带来了极佳的水平可扩展性，特别是在一个巨大的系统中。由于客户端自己做了一次哈希，那么我们很容易增加大量memcached到集群中。memcached</p> <p>之间没有相互通信，因此不会增加 memcached的负载；没有多播协议，不会网络通信量爆炸（implode）。</p> <p><strong>9、memcached和MySQL的query cache相比，有什么优缺点？</strong></p> <p>缺点：</p> <p>1）相比MySQL的query cache，把memcached引入应用中需要不少的工作量。MySQL的query cache，可以自动地缓存SQL查询的结果，被缓存的SQL查询可以被反复、快速的执行。</p> <p>优点：</p> <p>1）当修改表时，MySQL的query cache会立刻被刷新（flush）。当写操作很频繁时，MySQL的query cache会经常让所有缓存数据都失效。</p> <p>2）在多核CPU上，MySQL的query cache会遇到扩展问题（scalability issues）。在多核CPU上，query cache会增加一个全局锁（global lock）, 由于需要刷新更多的缓存数据，速度</p> <p>会变得更慢。</p> <p>3）在MySQL的query cache中，是不能存储任意的数据的（只能是SQL查询结果）。利用memcached，我们可以搭建出各种高效的缓存。比如，可以执行多个独立的查询，构建出一个</p> <p>用户对象（user object），然后将用户对象缓存到memcached中。而query cache是SQL语句级别的，不可能做到这一点。在小的网站中，query cache会有所帮助，但随着网站规模的</p> <p>增加，query cache的弊将大于利。</p> <p>4）query cache能够利用的内存容量受到MySQL服务器空闲内存空间的限制。给数据库服务器增加更多的内存来缓存数据，固然是很好的。但是，有了memcached，只要您有空闲的内</p> <p>存，都可以用来增加memcached集群的规模，然后您就可以缓存更多的数据。</p><strong>10、memcached和服务器的local cache（比如PHP的APC、mmap文件等）相比，有什么优缺点？</strong>  <p>1）首先，local cache面临着严重的内存限制，能够利用的内存容量受到（单台）服务器空闲内存空间的限制。</p> <p>2）local cache有一点比memcached和query cache都要好，那就是它不但可以存储任意的数据，而且没有网络存取的延迟。因此，local cache的数据查询更快。考虑把highly </p> <p>common的数据放在local cache中吧。如果每个页面都需要加载一些数量较少的数据，可以考虑把它们放在local cached。</p> <p>3）local cache缺少集体失效（group invalidation）的特性。在memcached集群中，删除或更新一个key会让所有的观察者觉察到。但是在local cache中, 我们只能通知所有的服务器</p> <p>刷新cache（很慢，不具扩展性）或者仅仅依赖缓存超时失效机制。</p> <p><strong>11、memcached的cache机制是怎样的？</strong></p> <p>Memcached主要的cache机制是LRU（最近最少用）算法+超时失效。当您存数据到memcached中，可以指定该数据在缓存中可以呆多久Which is forever, or some time in the </p> <p>future。如果memcached的内存不够用了，过期的slabs会优先被替换，接着就轮到最老的未被使用的slabs。</p> <p><strong>12、memcached如何实现冗余机制？</strong></p> <p>不实现！Memcached应该是应用的缓存层，从设计本身来京就不带有任何冗余机制。如果一个memcached节点失去了所有数据，应该可以从数据源（比如数据库）再次获取到数据。应</p> <p>用系统应该可以容忍节点的失效。如果担心节点失效会大大加重数据库的负担，那么可以采取一些办法。比如您可以<strong>增加更多的节点</strong>（来减少丢失一个节点的影响），<strong>热备节点</strong>（在其他节</p> <p>点down了的时候接管IP）等等。</p> <p><strong>13、memcached如何处理容错的？</strong></p> <p>在节点失效的情况下，集群没有必要做任何容错处理。如果发生了节点失效，应对的措施完全取决于用户。</p> <p>节点失效时，下面列出几种方案供您选择：</p> <p>1）忽略它！ 在失效节点被恢复或替换之前，还有很多其他节点可以应对节点失效带来的影响。</p> <p>2）把失效的节点从节点列表中移除。做这个操作千万要小心！在默认情况下（余数式哈希算法），客户端添加或移除节点，会导致所有的缓存数据不可用！因为哈希参照的节点列表变化</p> <p>了，大部分key会因为哈希值的改变而被映射到（与原来）不同的节点上。</p> <p>3）启动热备节点，接管失效节点所占用的IP。这样可以防止哈希紊乱（hashing chaos）。</p> <p>4）如果希望添加和移除节点，而不影响原先的哈希结果，可以使用一致性哈希算法（consistent hashing）。</p> <p>5）两次哈希（reshing）。当客户端存取数据时，如果发现一个节点down了，就再做一次哈希（哈希算法与前一次不同），重新选择另一个节点（需要注意的时，客户端并没有把down</p> <p>的节点从节点列表中移除，下次还是有可能先哈希到它）。如果某个节点时好时坏，两次哈希的方法就有风险了，好的节点和坏的节点上都可能存在脏数据（stale data）。</p> <p><strong>14、如何将memcached中item批量导入导出？</strong></p> <p>不应该这样做！Memcached是一个非阻塞的服务器。任何可能导致memcached暂停或瞬时拒绝服务的操作都应该值得深思熟虑。向memcached中批量导入数据往往不是您真正想要</p> <p>的！想象看，如果缓存数据在导出导入之间发生了变化，您就需要处理脏数据了；如果缓存数据在导出导入之间过期了，您又怎么处理这些数据呢？</p> <p>因此，批量导出导入数据并不像想象中的那么有用。不过在一个场景倒是很有用。如果您有大量的从不变化 的数据，并且希望缓存很快热（warm）起来，批量导入缓存数据是很有帮助</p> <p>的。</p> <p><strong>15、但是我确实需要把memcached中的item批量导出导入，怎么办？？</strong></p> <p>如果需要批量导出和导入，最可能的原因一般是重新生成缓存数据需要消耗很长的时间或者数据库坏了让您饱受痛苦。</p> <p>如果一个memcached节点down了让您很痛苦，那么必须对数据库做一些优化工作。比如处理"惊群"问题（ memcached节点都失效了，反复的查询让数据库不堪重负）或者存在优化不</p> <p>好的查询等。Memcached 并不是逃避优化查询的借口和方案。</p> <p>这里给出一些提示：</p> <p>使用MogileFS（或者CouchDB等类似的软件）在存储item，把item计算出来并dump到磁盘上。MogileFS可以很方便地覆写item，并提供快速地访问。甚至可以把MogileFS中的item</p> <p>缓存在memcached中，这样可以加快读取速度。 MogileFS+Memcached的组合可以加快缓存不命中时的响应速度，提高网站的可用性。 </p> <p>重新使用MySQL。MySQL的 InnoDB主键查询速度非常快。如果大部分缓存数据都可以放到VARCHAR字段中，那么主键查询的性能将更好。从memcached中按key查询几乎等价于</p> <p>MySQL的主键查询：将key 哈希到64-bit的整数，然后将数据存储到MySQL中。您可以把原始（不做哈希）的key存储都普通的字段中，然后建立二级索引来加快查询...key被动地失效，</p> <p>批量删除失效的key，等等。</p> <p><a name="how does memcached's authentication mechanisms work"></a><strong>16、memcached是如何做身份验证的？</strong></p> <p>没有身份认证机制！memcached是运行在应用下层的软件（身份验证应该是应用上层的职责）。memcached的客户端和服务器端之所以是轻量级的，部分原因就是完全没有实现身份验</p> <p>证机制。这样，memcached可以很快地创建新连接，服务器端也无需任何配置。如果您希望限制访问，您可以使用防火墙，或者让memcached监听unix domain socket。</p> <p><strong>17、memcached的多线程是什么？如何使用它们？</strong></p> <p>线程就是定律（threads rule）！在Steven Grimm和Facebook的努力下，memcached 1.2及更高版本拥有了多线程模式。多线程模式允许memcached能够充分利用多个CPU，并在</p> <p>CPU之间共享所有的缓存数据。memcached使用一种简单的锁机制来保证数据更新操作的互斥。相比在同一个物理机器上运行多个memcached实例，这种方式能够更有效地处理multi </p> <p>gets。如果系统的负载并不重，那么不需要启用多线程工作模式。如果您在运行一个拥有大规模硬件的、庞大的网站，将体验到看到多线程的好处。更多信息请参见：</p> <p><a href="http://code.sixapart.com/svn/memcached/trunk/server/doc/threads.txt">http://code.sixapart.com/svn/memcached/trunk/server/doc/threads.txt</a> 。</p> <p>简单地总结一下：命令解析（memcached在这里花了大部分时间）可以运行在多线程模式下。memcached内部对数据的操作是基于很多全局锁的（因此这部分工作不是多线程的）。未</p> <p>来对多线程模式的改进，将移除大量的全局锁，提高memcached在负载极高的场景下的性能。</p> <p><strong>18、memcached能接受的key的最大长度是多少？</strong></p> <p>memcached能接受的key的最大长度是250个字符。需要注意的是，250是memcached服务器端内部的限制。如果使用的Memcached客户端支持"key的前缀"或类似特性，那么key</p> <p>（前缀+原始key）的最大长度是可以超过250个字符的。推荐使用较短的key，这样可以节省内存和带宽。</p> <p><strong>19、memcached对item的过期时间有什么限制？</strong></p> <p>item对象的过期时间最长可以达到30天。memcached把传入的过期时间（时间段）解释成时间点后，一旦到了这个时间点，memcached就把item置为失效状态，这是一个简单但</p> <p>obscure的机制。</p> <p><strong>20、memcached最大能存储多大的单个item？</strong></p> <p>memcached最大能存储1MB的单个item。如果需要被缓存的数据大于1MB，可以考虑在客户端压缩或拆分到多个key中。</p> <p><strong>21、为什么单个item的大小被限制在1M byte之内？</strong></p> <p>简单的回答：因为内存分配器的算法就是这样的。</p> <p>详细的回答：</p> <p>1）Memcached的内存存储引擎，使用slabs来管理内存。内存被分成大小不等的slabs chunks（先分成大小相等的slabs，然后每个slab被分成大小相等chunks，不同slab的chunk大小</p> <p>是不相等的）。chunk的大小依次从一个最小数开始，按某个因子增长，直到达到最大的可能值。如果最小值为400B，最大值是1MB，因子是1.20，各个slab的chunk的大小依次是：</p> <p>slab1 - 400B；slab2 - 480B；slab3 - 576B ...slab中chunk越大，它和前面的slab之间的间隙就越大。因此，最大值越大，内存利用率越低。Memcached必须为每个slab预先分配内</p> <p>存，因此如果设置了较小的因子和较大的最大值，会需要为Memcached提供更多的内存。</p> <p>2）不要尝试向memcached中存取很大的数据，例如把巨大的网页放到mencached中。因为将大数据load和unpack到内存中需要花费很长的时间，从而导致系统的性能反而不好。如果</p> <p>确实需要存储大于1MB的数据，可以修改slabs.c：POWER_BLOCK的值，然后重新编译memcached；或者使用低效的malloc/free。另外，可以使用数据库、MogileFS等方案代替</p> <p>Memcached系统。</p> <p><strong>22、可以在不同的memcached节点上使用大小不等的缓存空间吗？如果这么做之后，memcached能够更有效地使用内存吗？</strong></p> <p>Memcache客户端仅根据哈希算法来决定将某个key存储在哪个节点上，而不考虑节点的内存大小。因此，可以在不同的节点上使用大小不等的内存作为缓存空间。但是一般可以这样做</p> <p>：拥有较多内存的节点上可以运行多个memcached实例，每个实例使用的内存跟其他节点上的实例相同。</p> <p><strong>23、什么是二进制协议，是否需要关注？</strong></p> <p>二进制协议尝试为端提供一个更有效的、可靠的协议，减少客户端/服务器端因处理协议而产生的CPU时间。根据Facebook的测试，解析ASCII协议是memcached中消耗CPU时间最多的</p> <p>环节。</p> <p><strong>24、memcached的内存分配器是如何工作的？为什么不适用malloc/free！？为何要使用slabs？</strong></p> <p>实际上，这是一个编译时选项。默认会使用内部的slab分配器，而且确实应该使用内建的slab分配器。最早的时候，memcached只使用malloc/free来管理内存。然而，这种方式不能与</p> <p>OS的内存管理以前很好地工作。反复地malloc/free造成了内存碎片，OS最终花费大量的时间去查找连续的内存块来满足malloc的请求，而不是运行memcached进程。slab分配器就是</p> <p>为了解决这个问题而生的。内存被分配并划分成chunks，一直被重复使用。因为内存被划分成大小不等的slabs，如果item的大小与被选择存放它的slab不是很合适的话，就会浪费一些内存。</p> <p><strong>25、memcached是原子的吗？</strong></p> <p>所有的被发送到memcached的单个命令是完全原子的。如果您针对同一份数据同时发送了一个set命令和一个get命令，它们不会影响对方。它们将被串行化、先后执行。即使在多线程模</p> <p>式，所有的命令都是原子的。然是，命令序列不是原子的。如果首先通过get命令获取了一个item，修改了它，然后再把它set回memcached，系统不保证这个item没有被其他进程</p> <p>（process，未必是操作系统中的进程）操作过。memcached 1.2.5以及更高版本，提供了gets和cas命令，它们可以解决上面的问题。如果使用gets命令查询某个key的item，</p> <p>memcached会返回该item当前值的唯一标识。如果客户端程序覆写了这个item并想把它写回到memcached中，可以通过cas命令把那个唯一标识一起发送给memcached。如果该item</p> <p>存放在memcached中的唯一标识与您提供的一致，写操作将会成功。如果另一个进程在这期间也修改了这个item，那么该item存放在memcached中的唯一标识将会改变，写操作就会</p> <p>失败。</p> <p><strong><font size="4">性能和客户端库方面的问题</font></strong></p> <p><strong>26、memcached没有我的database快，为什么？</strong></p> <p>在一对一比较中，memcached可能没有SQL查询快。但是，这不是memcached的设计目标。Memcached的目标是可伸缩性。当连接和请求增加的时候，memcached的性能将比</p> <p>大多数数据库查询好。可以先在高负载的环境（并发的连接和请求）中测试您的代码，然后再决定memcached是否适合您。</p> <p><strong>27、使用不同的客户端库，可以访问到memcached中相同的数据吗？</strong></p> <p>从技术上说，是可以的。但是可能会遇到下面三个问题：</p> <p>1）不同的库采用不同的方式序列化数据。举个例子，perl的Cache::Memcached使用Storable来序列化结构复杂的数据（比如hash references, objects, 等）。其他语言的客户端库很</p> <p>可能不能读取这种格式的数据。如果您要存储复杂的数据并且想被多种客户端库读取，那么您应该以简单的string格式来存储，并且这种格式可以被JSON、XML等外部库解析。</p> <p>2）从某个客户端来的数据被压缩了，从另一个客户端来的却没被压缩。</p> <p>3）各个客户端库可能使用不同的哈希算法（阶段一哈希）。在连接到多个memcached服务器端的情况下，客户端库根据自身实现的哈希算法把key映射到某台memcached上。正是因为</p> <p>不同的客户端库使用不同的哈希算法，所以被Perl客户端库映射到memcached A的key，可能又会被Python客户端库映射到memcached B，等等。Perl客户端库还允许为每台</p> <p>memcached指定不同的权重（weight），这也是导致这个问题的一个因素。</p> <p><a name="what is a consistent hashing client"></a><strong>28、什么是一致性哈希的客户端？</strong></p> <p>这里有一篇文章很好地解释了它的用处：<a href="http://www.last.fm/user/RJ/journal/2007/04/10/392555">http://www.last.fm/user/RJ/journal/2007/04/10/392555</a> 。</p> <p><a name="client faq"></a>客户端可以通过"前缀"来给key设置一个域（命名空间）。例如，在一个共享主机的环境中，可以将客户姓名作为"前缀"，为key创建一个特定的域。在存储数据的时候，"前缀"可以用在</p> <p>key上，但是不应该参与哈希计算。目前，memcached自己还没有实现针对复杂结构数据的序列化方法，JSON则是一种被广泛使用的对象序列化格式。</p> <p><font size="4"><strong>哈希 / 键分布</strong></font>  <p><strong>29、什么时候失效的数据项会从缓存中删除？</strong>  <p>memcached 使用懒失效，当客户端请求数据项时， memcached 在返回数据前会检查失效时间来确定数据项是否已经失效。同样地，当添加一个新的数据项时，如果缓存已经满了， memcached 就会先替换失效的数据项，然后才是缓存中最少使用的数据项。  <p><font size="4"><strong>命名空间</strong></font>  <p><strong>30、memcached 不支持命名空间。以下提供几种模仿命名空间的方式：</strong>  <p>1）用键的前缀模仿命名空间：在真实的键之前加入有意义的前缀。  <p>2）用命名空间删除数据项：尽管 memcached 不支持使用任何类型的通配符或命名空间来完成删除操作，但是可以采用一些技巧来替代：  <p>在 PHP 中使用一个叫 foo 的命名空间：$ns_key = $memcache-&gt;get("foo_namespace_key");  <p>// if not set, initialize it  <p>if($ns_key=false) $memcache-&gt;set("foo_namespace_key", rand(1, 10000));  <p>$my_key = "foo_".$ns_key."_12345";  <p>清除命名空间：$memcache-&gt;increment("foo_namespace_key");  <p><font size="4"><strong>应用设计</strong></font></p> <p><strong>31、在设计应用时，可以通过Memcached缓存那些内容？</strong>  <p><strong>1）缓存简单的查询结果：</strong>查询缓存存储了给定查询语句对应的整个结果集，最合适缓存那些<strong>经常被用到，但不会改变的 SQL 语句对查询到的结果集，比如载入特定的过滤内容。</strong>  <p>$key = md5('SELECT * FROM rest_of_sql_statement_goes_here');  <p>if ($memcache-&gt;get($key)) {  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ` return $memcache-&gt;get($key);`  <p>}else {  <p>&nbsp;&nbsp;&nbsp; ` // Run the query and transform the result data into your final dataset form`  <p>&nbsp;&nbsp;&nbsp; ` $result = $query_results_mangled_into_most_likely_an_array`  <p>&nbsp;&nbsp;&nbsp;&nbsp; ` $memcache-&gt;set($key, $result, TRUE, 86400); // Store the result of the query for a day`  <p>&nbsp;&nbsp;&nbsp; ` return $result;`  <p>}  <p>记住，如果查询语句对应的结果集改变，该结果集不会展现出来。这种方法不总是有用，但它确实让工作变得比较快。  <p><strong>2）缓存简单的基于行的查询结果：</strong>基于行的缓存会检查缓存数据key的列表，那些在缓存中的行可以直接被取出，不在缓存中的行将会从数据库中取出并以唯一的键为标识缓存起来，最  <p>后加入到最终的数据集中返回。随着时间的推移，大多数数据都会被缓存，这也意味着相比与数据库，查询语句会更多地从 memcached 中得到数据行。如果数据是相当静态的，我们可  <p>以设置一个较长的缓存时间。  <p><strong>基于行的缓存模式对下面这种搜索情况特别有用</strong>：数据集本身很大或是数据集是从多张表中得到，而数据集取决于查询的输入参数但是查询的结果集之间的有重复部分。  <p>比如，如果你有用户 A ， B ， C ， D ， E 的数据集。你去点击一张显示用户 A ， B ， E 信息的页面。首先， memcached 得到 3 个不同的键，每个对应一个用户去缓存中查找，全部未  <p>命中。然后就到数据库中用 SQL 查询得到 3 个用户的数据行，并缓存他们。  <p>现在，你又去点击另一张显示显示 C ， D ， E 信息的页面。当你去查找 memcached 时， C ， D 的数据并没有被命中，但我们命中了 E 的数据。然后从数据库得到 C ， D 的行数据，缓  <p>存在 memcached 中。至此以后，无论这些用户信息怎样地排列组合，任何关于 A ， B ， C ， D ， E 信息的页面都可以从 memcached 得到数据了。  <p><strong>3）缓存的不只是 SQL 数据，可以缓存最终完成的部分显示页面，以节省CPU计算时间</strong></p> <p>例如正在制作一张显示用户信息的页面，你可能得到一段关于用户的信息（姓名，生日，家庭住址，简介），然后你可能会将 XML 格式的简介信息转化为 HTML 格式或做其他的一些工  <p>作。相比单独存储这些属性，你可能更愿意<strong>存储经过渲染的数据块</strong>。那时你就可以简单地取出被预处理后的 HTML 直接填充在页面中，这样节省了宝贵的 CPU 时间。  <p><strong>32、使用分层的缓存</strong>  <p>memcached 可以高速处理大量的缓存数据，但是还是要根据系统的情况考虑维护多层的缓存结构。例如除了memcached缓存之外，还可以通过本地缓存（如ehcache、oscache等）建  <p>立起多级缓存。例如，可以采用本地缓存缓存一些基本数据，例如少量但访问频繁的数据（如产品分类，连接信息，服务器状态变量，应用配置变量等），缓存这些数据并让他们尽可能的  <p>接近处理器是有意义的 , 这样可以帮助减少生成页面的时间，并且在 memcached 失效的情况下可以增加可靠性。  <p><strong>33、当数据更新时需要更新缓存</strong>  <p>用户编辑了自己的信息，当保存信息到数据库时，需要更新缓存中的数据或是简单地删除老的数据。如果马上更新数据，要防止从数据库读取那些刚刚更新过的数据。当用户习惯性地重新  <p>载入自己的用户信息来确认是否修改成功时，数据将从缓存中直接取出，这时他们获得了最新的数据。  <p><strong>34、模拟带锁的添加命令</strong></p> <p>如果你实在需要锁，你可以通过“添加”命令模仿锁的功能。尽管在未命中的情况下它不是那么有用，但如果你用它缓存平常的数据（应用服务器池的元数据）那还是有用的。  <p>比如，你要更新键 A 。  <p>1. 添加一个 "lock:A" 的键，这个键有一个持续几秒的过期时间（足够长以使你能完成计算和更新，也不要很长，因为如果锁进程挂了，这个键不会立即释放）  <p>2. 如果添加操作成功了，你就拥有了锁：从缓存获取键 A 的数据；利用客户端程序更改数据；更新缓存键 A 的数据；删除键 "lock:A" 。如果你不需要立即再次更新，就让它存活直到失效。  <p>3. 如果添加操作失败，说明有人获取了锁。这时让应用做些合适的事，比如返回老数据，等待后重试，或是其他的。  <p>以上这些操作类似 MySQL 将 GET_LOCK 的 timeout 值设置成 0 。没有办法在 memcached 中通过互斥锁模拟 GET_LOCK() 的 timeout 操作。  <p><strong>35、预热你的缓存</strong>  <p>如果你有一个很高访问率的站点，并且你正想加入故障恢复功能或是其他全新的功能，你最终可能会碰到空缓存的问题。一开始缓存是空的，然后一大群人点击你的站点，在填充缓存的过  <p>程中，你的数据库可能会承受不住压力。为了解决这一问题，你可以试试任何可行的方法来 " 温暖 " 你的Memcached。方法：可以写一些脚本来缓存通用的页面；也可以写一个命令行工  <p>具来填充缓存。你可以在高峰时刻在缓存里填充一些内容。  <p>参考网页:  <p><a title="http://shwangking-126-com.iteye.com/blog/284937" href="http://shwangking-126-com.iteye.com/blog/284937">http://shwangking-126-com.iteye.com/blog/284937</a></p><img src ="http://www.blogjava.net/chhbjh/aggbug/370472.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chhbjh/" target="_blank">阳光咖啡</a> 2012-02-21 22:54 <a href="http://www.blogjava.net/chhbjh/archive/2012/02/21/370472.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux常用命令集锦（二）</title><link>http://www.blogjava.net/chhbjh/archive/2012/02/01/369192.html</link><dc:creator>阳光咖啡</dc:creator><author>阳光咖啡</author><pubDate>Wed, 01 Feb 2012 14:16:00 GMT</pubDate><guid>http://www.blogjava.net/chhbjh/archive/2012/02/01/369192.html</guid><wfw:comment>http://www.blogjava.net/chhbjh/comments/369192.html</wfw:comment><comments>http://www.blogjava.net/chhbjh/archive/2012/02/01/369192.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chhbjh/comments/commentRss/369192.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chhbjh/services/trackbacks/369192.html</trackback:ping><description><![CDATA[<p><strong>1、查看端口被哪个应用程序占用</strong></p> <p>[root@localhost conf]# netstat –ntlp</p> <p>netstat命令：显示网络状态</p> <p>参数：</p> <p>n&nbsp;&nbsp;&nbsp; 直接使用IP地址，而不通过域名服务器</p> <p>t&nbsp;&nbsp;&nbsp;&nbsp; 显示TCP传输协议的连线状况</p> <p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 显示监控中的服务器的Socket</p> <p>p&nbsp;&nbsp;&nbsp; 显示正在使用Socket的程序识别码和程序名称</p> <p><strong>2、查看Apache是否安装以及安装路径和版本</strong></p> <p>命令：<font color="#000000">Apachectl –v</font></p> <p>[root@localhost apache]# apachectl -v<br>Server version: Apache/2.2.15 (Unix)<br>Server built:&nbsp;&nbsp; Jul&nbsp; 7 2011 11:27:40</p> <p>通过这个命令可以获得当前部署的Apache的版本和发行时间。</p> <p>如果用rpm安装，可用rpm –d httpd命令查看是否已经安装过。</p> <p><strong>3、查找安装的指定程序</strong></p> <p>1）如果是rpm套件，可用：</p> <p>[root@localhost apache]# rpm -qa | grep xxx</p> <p>其中：</p> <p>q&nbsp;&nbsp;&nbsp;&nbsp; 使用询问模式，当遇到任何问题时，rpm指令会先询问用户</p> <p>a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查询所有套件</p> <p>2）如果是源码安装的，可以用：</p> <p>whereis xxx</p> <p><strong>4、RPM套件基本操作</strong></p> <p>1）安装 rpm 套件</p> <p>命令：rpm -ihv </p> <p>例子：rpm -ihv bind-8.2.1-7.i386.rpm</p> <p>2）更新rpm套件</p> <p>命令：rpm -Uhv</p> <p>例子：rpm -Uhv bind-8.2.1-7.i386.rpm 　</p> <p>3）查询已安装的rpm 套件</p> <p>命令：rpm -qa | grep xxx</p> <p>例子：rpm -qa | grep bind rpm -e </p> <p>4）删除 rpm 套件</p> <p>命令：rpm –e</p> <p>例子：rpm -e bind-8.2.1-7.i386.rpm </p> <p>注意: 删除服务前应先停止</p> <p>5）强制删除rpm套件</p> <p>命令: rpm -e –nodeps xxxxxx.rpm</p> <p>rpm参数说明：</p> <p>e&nbsp;&nbsp;&nbsp; 删除指定的套件</p> <p>i&nbsp;&nbsp;&nbsp;&nbsp; 显示套件的相关信息</p> <p>h&nbsp;&nbsp; 套件安装时列出标记</p> <p>v&nbsp;&nbsp;&nbsp; 显示指令执行过程</p> <p>U&nbsp;&nbsp; 升级指定的套件档</p> <p>nodeps&nbsp;&nbsp; 不考虑包间的依赖关系</p> <p><strong>5、查找程序进程</strong></p> <p>1）ps -ef | grep xxx</p> <p>ps命令：报告程序状况</p> <p>参数：</p> <p>-e&nbsp; 显示所有终端机下执行的程序</p> <p>-f&nbsp;&nbsp; 显示UID,PPIP,C与STIME栏位</p> <p>例子：ps -ef | grep httpd</p> <p>2）netstat –ntlp</p> <p>说明请参考前面的介绍。</p> <p><strong>6、杀死Linux进程</strong></p> <p>1）kill pid</p> <p>注释：标准的kill命令通常都能达到目的。终止有问题的进程，并把进程的资源释放给系统。然而，如果进程启动了子进程，只杀死父进程，子进程仍在运行，因此仍消耗资源。为了防止这些所谓的“僵尸进程”，应确保在杀死父进程之前，先杀死其所有的子进程。</p> <p>2）kill -l pid</p> <p>注释：当使用该选项时，kill命令也试图杀死所留下的子进程。但这个命令也不是总能成功,或许仍然需要先手工杀死子进程，然后再杀死父进程。</p> <p>3）kill -temp ppid</p> <p>注释：给父进程发送一个TERM信号，试图杀死它和它的子进程。</p> <p>4）killall httpd</p> <p>注释：killall命令杀死同一进程组内的所有进程。其允许指定要终止的进程的名称，而非PID。</p> <p>5）kill -HUP PID</p> <p>注释：该命令让Linux和缓的执行进程关闭，然后立即重启。在配置应用程序的时候，这个命令很方便，在对配置文件修改后需要重启进程时就可以执行此命令。</p> <p>5）kill -9 PID</p> <p>注释：终极大招。这个强大和危险的命令迫使进程在运行时突然终止，进程在结束后不能自我清理。危害是导致系统资源无法正常释放，一般不推荐使用，除非其他办法都无效。由于只能</p> <p>通过终止父进程来消除僵尸进程，因此当使用此命令时，一定要通过ps -ef确认没有剩下任何僵尸进程。如果僵尸进程被init收养，问题就比较严重了。杀死init进程意味着关闭系统。</p> <p>如果系统中有僵尸进程，并且其父进程是init，而且僵尸进程占用了大量的系统资源，那么就需要在某个时候重启机器以清除进程表了。  <p><strong>7、常用的防火墙操作（iptables）</strong>  <p>[root@localhost httpd-2.2.22]# /sbin/iptables&nbsp; -I&nbsp;&nbsp; INPUT&nbsp; -p&nbsp; tcp&nbsp; --dport&nbsp;&nbsp; 80&nbsp;&nbsp;&nbsp; -j&nbsp;&nbsp; ACCEPT&nbsp; </p> <p>[root@localhost httpd-2.2.22]# /sbin/iptables&nbsp; -I&nbsp;&nbsp; INPUT&nbsp; -p&nbsp; tcp&nbsp; --dport&nbsp;&nbsp; 443&nbsp; -j&nbsp;&nbsp; ACCEPT</p> <p>[root@localhost httpd-2.2.22]# /etc/init.d/iptables save  <p>这样重启计算机后,防火墙默认便开放了80和443端口。  <p>也可以通过以下方式不重启计算机，完成规则的添加：  <p>#/etc/init.d/iptables restart  <p>查看防火墙信息：  <p>#/etc/init.d/iptables status  <p>关闭防火墙服务：  <p>#/etc/init.d/iptables stop  <p>永久关闭防火墙：</p> <p>#chkconfig –level 35 iptables off </p> <p>参考文章：</p> <p>1、CentOS Linux防火墙配置及关闭 </p><img src ="http://www.blogjava.net/chhbjh/aggbug/369192.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chhbjh/" target="_blank">阳光咖啡</a> 2012-02-01 22:16 <a href="http://www.blogjava.net/chhbjh/archive/2012/02/01/369192.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>探秘Java虚拟机&amp;mdash;&amp;mdash;内存管理与垃圾回收（补充说明）</title><link>http://www.blogjava.net/chhbjh/archive/2012/01/29/368973.html</link><dc:creator>阳光咖啡</dc:creator><author>阳光咖啡</author><pubDate>Sun, 29 Jan 2012 09:24:00 GMT</pubDate><guid>http://www.blogjava.net/chhbjh/archive/2012/01/29/368973.html</guid><wfw:comment>http://www.blogjava.net/chhbjh/comments/368973.html</wfw:comment><comments>http://www.blogjava.net/chhbjh/archive/2012/01/29/368973.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chhbjh/comments/commentRss/368973.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chhbjh/services/trackbacks/368973.html</trackback:ping><description><![CDATA[<p>说明：以下大部分文字均摘自网络上的某些“童鞋”的优秀文章。</p> <p><strong>一、对于GC的性能其实主要考虑以下两个方面：</strong></p> <p>&nbsp;&nbsp;&nbsp;&nbsp; 1、吞吐率throughput【工作时间（不包括GC的时间）占总运行的时间比】</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; 2、暂停pause（GC发生时应用程序无法响应用户的请求）</p> <p><strong>二、对于GC的性能可以从以下方面考虑：</strong></p> <p><strong>1、整个堆空间</strong></p> <p>对于Server端的应用程序，有以下最佳实践：</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; 1）对于JVM分配尽可能多的内存空间。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; 2）固定堆空间的大小，将Xms和Xmx设为一样的值。如果让JVM自行控制堆空间大小的话，虚拟机启动时分配的堆空间比较小，如果在程序运行过程中还需要初始化很多对象，虚拟</p> <p>机就必须重复地增加内存，造成GC频率的增加。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; 3）横向增加服务器的数量，为程序服务的JVM内存总量也随着增大。</p> <p><strong>2、新生代</strong></p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 从整体上看，新生代越大，minor GC就会越少。但由于我们一般是固定的堆内存空间，因此更大的新生代也就意味着更小的老生代，更小的老生代会带来更多的Full GC(Full GC会伴随</p> <p>有minor GC)。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 参数NewRatio反映的是新生代和老生代的大小比例。NewSize和MaxNewSize反映的是新生代空间的下限和上限，将这两个值设为一样就固定了新生代的大小（或者直接通过指定</p> <p>Xms、Xmx和Xmn的大小来固定新生代的大小）。SurvivorRatio可以指定survivor区的大小，SurvivorRatio是eden区和survior区的大小比例。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一般而言，server端的app会有以下最佳实践：  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1）首先固定heap空间的大小，然后设定最佳的新生代空间的大小；  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2）如果堆空间固定后，增加新生代的大小就意味着减小老生代的大小。因此在调节时应特别留意，让老生代至少能够保留10%-20%的空余空间，并能够容纳所有live的对象。</p> <p><strong>三、最佳实践：</strong></p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>1）年轻代大小的选择 </strong></p> <p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 响应时间优先的应用</strong>：尽可能增大新生代的大小，直到接近系统的最低响应时间限制(根据实际情况选择)。在此种情况下，新生代收集发生的频率也是最小的。同时，减少到达年老代</p> <p>的对象，从而减少Full GC的发生几率。 </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>吞吐量优先的应用：</strong>尽可能增大新生代的大小，可能到达Gbit的程度。因为对响应时间没有要求，垃圾收集可以并行进行，一般适合8CPU以上的应用系统。 </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>避免设置过小：</strong>当新生代设置过小时会导致：1、minor GC的次数更加频繁&nbsp;&nbsp;&nbsp; 2、可能导致minor GC对象直接进入老生代，如果此时老生代满了,会触发Full GC.</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>2）年老代大小选择 </strong></p> <p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 响应时间优先的应用</strong>：老生代使用并发收集器（CMS GC），所以其大小需要小心设置，一般要考虑并发会话率和会话持续时间等一些参数。如果堆设置小了,可以会形成内存碎片，高</p> <p>回收频率以及应用暂停。而使用传统的标记清除方式，如果堆设置大了,则需要较长的收集时间。最优化的方案,一般需要参考以下数据获得：并发垃圾收集信息、永久代并发收集次数、传</p> <p>统GC信息、花在新生代和老生代回收上的时间比例。 </p> <p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 吞吐量优先的应用</strong>：一般吞吐量优先的应用都有一个很大的新生代和一个较小的老生代。原因是这样可以尽可能回收掉大部分短期对象，减少中期的对象，而老生代尽存放长期存活对象。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; <strong>3）其他</strong></p> <p>&nbsp;&nbsp;&nbsp;&nbsp; <strong>较小堆引起的碎片问题：</strong>因为老生代的并发收集器使用标记清除算法，所以不会对堆进行压缩。当收集器回收时，它会把相邻的空间进行合并，这样可以分配给较大的对象。但是，当</p> <p>堆空间较小时，运行一段时间以后，就会出现"碎片"，如果并发收集器找不到足够的空间，那么并发收集器将会停止，然后使用传统的标记清除方式进行回收。如果出现"碎片"，可能需要</p> <p>进行如下配置：</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; -XX:+UseCMSCompactAtFullCollection：使用并发收集器时,开启对年老代的压缩。</p> <p>&nbsp;&nbsp;&nbsp; -XX:CMSFullGCsBeforeCompaction=0：上面配置开启的情况下，这里设置多少次Full GC后,对年老代进行压缩。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; <strong>用64位操作系统。</strong>Linux下64位的jdk比32位jdk要慢一些，但是吃得内存更多，吞吐量更大。 </p> <p>&nbsp;&nbsp;&nbsp;&nbsp; <strong>XMX和XMS设置一样大，</strong><strong>MaxPermSize和MinPermSize设置一样大，这样可以减轻伸缩堆大小带来的压力 。</strong></p> <p>&nbsp;&nbsp;&nbsp;&nbsp; <strong>使用CMS GC的好处是用尽量少的新生代，经验值是128M－256M， 然后老生代利用CMS并行收集， 这样能保证系统低延迟的吞吐效率</strong>。 实际上CMS GC的收集停顿时间非常的短，</p> <p>2G的内存大约20－80ms的应用程序停顿时间。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; <strong>减少程序停顿时间</strong>：系统停顿的时间可能是GC的问题也可能是程序的问题，多用jmap和jstack查看或者killall -3 java，然后查看java控制台日志，能看出很多问题。有一次，网站突然</p> <p>很慢，利用jstack一看，原来是自己写的URLConnection连接太多没有释放造成的。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; <strong>程序应用缓存的问题：</strong>如果程序应用了缓存，那么老生代应该设置的大一些，缓存的HashMap不应该无限制增长，建议采用LRU算法的Map做缓存，LRU Map（例如Jakarta </p> <p>Commons中提供的org.apache.commons.collections.map.LRUMap）的最大长度也要根据实际情况设定。 </p> <p>&nbsp;&nbsp;&nbsp;&nbsp; <strong>采用并发回收时，新生代小一点，老生代要大，因为老生代用的是并发回收，即使时间长点也不会影响其他程序继续运行，网站不会停顿。</strong></p> <p>&nbsp;&nbsp;&nbsp;&nbsp; <strong>JVM 参数的设置</strong>(特别是 –Xmx –Xms –Xmn -XX:SurvivorRatio&nbsp; -XX:MaxTenuringThreshold等参数的设置没有一个固定的公式，需要根据PV、老生代实际数据、新生代GC次数等</p> <p>多方面来衡量。为了避免promotion faild，可能会导致xmn设置偏小，也意味着新生代GC的次数会增多，处理并发访问的能力下降等问题。每个参数的调整都需要经过详细的性能测试，</p> <p>才能找到特定应用的最佳配置。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; <strong>打印GC日志</strong>：调试的时候设置一些打印参数，如-XX:+PrintClassHistogram -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Xloggc:log/gc.log，这样可</p> <p>以从gc.log里看出一些问题出来。</p> <p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4）promotion failed（晋升失败）：</strong>第一个原因是担保空间不够，担保空间里的对象还不应该被移动到老生代，但新生代又有很多对象需要放入担保空间；第二个原因是老生代没有足够的空间接纳来自新生代的对象；这两种情况都会转向Full GC，网站停顿时间较长。  <p>&nbsp;&nbsp;&nbsp;&nbsp; <strong>解决方方案一</strong>：  <p>&nbsp;&nbsp;&nbsp;&nbsp; 第一个原因我的最终解决办法是去掉担保空间，设置-XX:SurvivorRatio=65536 -XX:MaxTenuringThreshold=0即可，第二个原因我的解决办法是设置  <p>CMSInitiatingOccupancyFraction为某个值（假设70），这样老生代空间到70%时就开始执行CMS，老生代有足够的空间接纳来自新生代的对象。  <p>&nbsp;&nbsp;&nbsp;&nbsp; <strong>方案一的改进方案</strong>：  <p>&nbsp;&nbsp;&nbsp;&nbsp; 方案一中没有用到担保空间，所以老生代容易满，CMS执行会比较频繁。我改善了一下，还是用担保空间，但是把担保空间加大，这样也不会有promotion failed。具体操作上，32位Linux和64位Linux好像不一样，64位系统似乎只要配置MaxTenuringThreshold参数，CMS还是有暂停。为了解决暂停问题和promotion failed问题，最后我设置-  <p>XX:SurvivorRatio=1 ，并把MaxTenuringThreshold去掉，这样即没有暂停又不会有promotoin failed，而且更重要的是，老生代和永久代上升非常慢（因为好多对象到不了年老代就  <p>被回收了），所以CMS执行频率非常低，好几个小时才执行一次，这样，服务器都不用重启了。  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -Xmx4000M -Xms4000M -Xmn600M -XX:PermSize=500M -XX:MaxPermSize=500M -Xss256K -XX:+DisableExplicitGC -XX:SurvivorRatio=1  <p>-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0  <p>-XX:+CMSClassUnloadingEnabled -XX:LargePageSizeInBytes=128M -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly  <p>-XX:CMSInitiatingOccupancyFraction=80 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+PrintClassHistogram -XX:+PrintGCDetails -XX:+PrintGCTimeStamps  <p>-XX:+PrintHeapAtGC -Xloggc:log/gc.log  <p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5）CMSInitiatingOccupancyFraction值与Xmn的关系公式</strong>  <p>&nbsp;&nbsp;&nbsp;&nbsp; 上面介绍了promontion faild产生的原因是Eden空间不足的情况下将Eden与From survivor中的存活对象存入To survivor区时，To survivor区的空间不足，再次晋升到old gen区，</p> <p>而old gen区内存也不够的情况下产生了promontion faild从而导致full gc。那可以推断出：eden+from survivor &lt; old gen区剩余内存时，不会出现promontion faild的情况，即：</p> <p>(Xmx-Xmn)*(1-CMSInitiatingOccupancyFraction/100)&gt;=[Xmn-Xmn/(SurvivorRatior+2)]&nbsp; 进而推断出：</p> <p>CMSInitiatingOccupancyFraction &lt;={(Xmx-Xmn)-[Xmn-Xmn/(SurvivorRatior+2)]}/(Xmx-Xmn)*100  <p>&nbsp;&nbsp;&nbsp;&nbsp; 例如：  <p>&nbsp;&nbsp;&nbsp;&nbsp; 当Xmx=128 Xmn=36 SurvivorRatior=1时 CMSInitiatingOccupancyFraction&lt;=((128.0-36)-(36-36/(1+2)))/(128-36)*100 =73.913  <p>&nbsp;&nbsp;&nbsp;&nbsp; 当Xmx=128 Xmn=24 SurvivorRatior=1时 CMSInitiatingOccupancyFraction&lt;=((128.0-24)-(24-24/(1+2)))/(128-24)*100=84.615…  <p>&nbsp;&nbsp;&nbsp;&nbsp; 当Xmx=3000 Xmn=600 SurvivorRatior=1时&nbsp; CMSInitiatingOccupancyFraction&lt;=((3000.0-600)-(600-600/(1+2)))/(3000-600)*100=83.33  <p>&nbsp;&nbsp;&nbsp;&nbsp; 当CMSInitiatingOccupancyFraction低于70% 需要调整Xmn或SurvivorRatior值。  <p>&nbsp;<strong>四、内存泄露的分析</strong>  <p><img src="http://dl.iteye.com/upload/attachment/0062/2908/b91e4497-8adf-3f84-8e12-41a33b4c1674.jpg" width="888" height="410">  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HPjmeter是一个GC的图形化分析工具,由上图可以看出GC始终无法回收heap内存空间，以使heap内存空间的使用量持续升高，明显存在内存泄露的可能性。定位内存泄露，可以生  <p>成dump文件，并利用MAT进行分析，查找原因。  <p>&nbsp;&nbsp;&nbsp;&nbsp; 内存分析工具：  <p>&nbsp;&nbsp;&nbsp;&nbsp; 详细信息可参考文章<a href="http://qa.taobao.com/?p=14264">http://qa.taobao.com/?p=14264</a>。  <p>&nbsp;&nbsp;&nbsp;&nbsp; JVM内存状况查看方案及工具：<a href="http://www.51testing.com/html/58/n-237858.html">http://www.51testing.com/html/58/n-237858.html</a>  <p>&nbsp;&nbsp;&nbsp;&nbsp; 使用 Eclipse Memory Analyzer 进行堆转储文件分析：<a href="http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-ma/index.html?ca=drs-">http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-ma/index.html?ca=drs-</a>  <p>&nbsp;&nbsp;&nbsp;&nbsp; 参考文献：  <p>&nbsp;&nbsp;&nbsp; 1、<a href="http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html">JVM系列三:JVM参数设置、分析</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a title="http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html" href="http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html">http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html</a>&nbsp; <p>&nbsp;&nbsp;&nbsp; 2、<a href="http://hbase.iteye.com/blog/1356450">一个典型的OutOfMemory分析过程</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://hbase.iteye.com/blog/1356450">http://hbase.iteye.com/blog/1356450</a>  <p>&nbsp;&nbsp;&nbsp; 3、使用MAT分析内存泄露&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://qa.taobao.com/?p=14264">http://qa.taobao.com/?p=14264</a>  <p>&nbsp;&nbsp;&nbsp; 4、JVM内存状况查看方法和分析工具&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.51testing.com/html/58/n-237858.html">http://www.51testing.com/html/58/n-237858.html</a>  <p>&nbsp;&nbsp;&nbsp; 5、使用 Eclipse Memory Analyzer 进行堆转储文件分析：<a href="http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-ma/index.html?ca=drs-">http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-ma/index.html?ca=drs-</a></p><img src ="http://www.blogjava.net/chhbjh/aggbug/368973.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chhbjh/" target="_blank">阳光咖啡</a> 2012-01-29 17:24 <a href="http://www.blogjava.net/chhbjh/archive/2012/01/29/368973.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>探秘Java虚拟机&amp;mdash;&amp;mdash;内存管理与垃圾回收</title><link>http://www.blogjava.net/chhbjh/archive/2012/01/28/368936.html</link><dc:creator>阳光咖啡</dc:creator><author>阳光咖啡</author><pubDate>Sat, 28 Jan 2012 13:41:00 GMT</pubDate><guid>http://www.blogjava.net/chhbjh/archive/2012/01/28/368936.html</guid><wfw:comment>http://www.blogjava.net/chhbjh/comments/368936.html</wfw:comment><comments>http://www.blogjava.net/chhbjh/archive/2012/01/28/368936.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/chhbjh/comments/commentRss/368936.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chhbjh/services/trackbacks/368936.html</trackback:ping><description><![CDATA[<p>本文主要是基于Sun JDK 1.6 Garbage Collector（作者：毕玄）的整理与总结，原文请读者在网上搜索。</p> <p><strong>1、Java虚拟机运行时的数据区</strong></p> <p><a href="http://www.blogjava.net/images/blogjava_net/chhbjh/Windows-Live-Writer/2d08114b62d1_AA6A/image_5.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.blogjava.net/images/blogjava_net/chhbjh/Windows-Live-Writer/2d08114b62d1_AA6A/image_thumb_1.png" width="475" height="398"></a></p> <p><strong>2、常用的内存区域调节参数</strong></p> <p><strong>-Xms</strong>：初始堆大小，默认为物理内存的1/64(&lt;1GB)；默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时，JVM就会增大堆直到-Xmx的最大限制</p> <p><strong>-Xmx</strong>：最大堆大小，默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时，JVM会减少堆直到 -Xms的最小限制</p> <p><strong>-Xmn</strong>：新生代的内存空间大小，<strong>注意</strong>：此处的大小是（eden+ 2 survivor space)。与jmap -heap中显示的New gen是不同的。整个堆大小=新生代大小 + 老生代大小 + 永久代大小。 <br>在保证堆大小不变的情况下，增大新生代后,将会减小老生代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。</p> <p><strong>-XX:SurvivorRatio</strong>：新生代中Eden区域与Survivor区域的容量比值，默认值为8。两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10。</p> <p><strong>-Xss</strong>：每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。应根据应用的线程所需内存大小进行适当调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的，不能无限生成，经验值在3000~5000左右。一般小的应用， 如果栈不是很深， 应该是128k够用的，大的应用建议使用256k。这个选项对性能影响比较大，需要严格的测试。和threadstacksize选项解释很类似,官方文档似乎没有解释,在论坛中有这样一句话:"-Xss is translated in a VM flag named ThreadStackSize”一般设置这个值就可以了。</p> <p><strong>-XX:PermSize</strong>：设置永久代(perm gen)初始值。默认值为物理内存的1/64。</p> <p><strong>-XX:MaxPermSize</strong>：设置持久代最大值。物理内存的1/4。</p> <p><strong>3、内存分配方法</strong></p> <p>1）堆上分配&nbsp;&nbsp; 2）栈上分配&nbsp; 3）堆外分配（DirectByteBuffer或直接使用Unsafe.allocateMemory,但不推荐这种方式）</p> <p><strong>4、监控方法</strong></p> <p>1）系统程序运行时可通过jstat –gcutil来查看堆中各个内存区域的变化以及GC的工作状态； <br>2）启动时可添加-XX:+PrintGCDetails&nbsp; –Xloggc:&lt;file&gt;输出到日志文件来查看GC的状况； <br>3）jmap –heap可用于查看各个内存空间的大小；</p> <p><strong>5）断代法可用GC汇总</strong></p> <p><a href="http://www.blogjava.net/images/blogjava_net/chhbjh/Windows-Live-Writer/2d08114b62d1_AA6A/image_3.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.blogjava.net/images/blogjava_net/chhbjh/Windows-Live-Writer/2d08114b62d1_AA6A/image_thumb.png" width="581" height="460"></a></p> <p>一、新生代可用GC</p> <p>1）串行GC(Serial Copying)：client模式下默认GC方式，也可通过-XX:+UseSerialGC来强制指定；默认情况下 eden、s0、s1的大小通过-XX:SurvivorRatio来控制，默认为8，含义 <br>为eden:s0的比例，启动后可通过jmap –heap [pid]来查看。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 默认情况下，仅在TLAB或eden上分配，只有两种情况下会在老生代分配： <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、需要分配的内存大小超过eden space大小； <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、在配置了PretenureSizeThreshold的情况下，对象大小大于此值。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 默认情况下，触发Minor GC时：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 之前Minor GC晋级到old的平均大小 &lt; 老生代的剩余空间 &lt; eden+from Survivor的使用空间。当HandlePromotionFailure为true，则仅触发minor gc；如为false，则触发full GC。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 默认情况下，新生代对象晋升到老生代的规则：</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; 1、经历多次minor gc仍存活的对象，可通过以下参数来控制：以MaxTenuringThreshold值为准，默认为15。<br>&nbsp;&nbsp;&nbsp;&nbsp; 2、to space放不下的，直接放入老生代；</p> <p>2）并行GC（ParNew）：CMS GC时默认采用，也可采用-XX:+UseParNewGC强制指定；垃圾回收的时候采用多线程的方式。</p> <p>3）并行回收GC(Parallel Scavenge)：server模式下默认的GC方式，也可采用-XX:+UseParallelGC强制指定；eden、s0、s1的大小可通过-XX:SurvivorRatio来控制，但默认情况下<br>以-XX:InitialSurivivorRatio为准，此值默认为8，<strong>代表的为新生代大小 : s0</strong>，这点要特别注意。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 默认情况下，当TLAB、eden上分配都失败时，判断需要分配的内存大小是否 &gt;= eden space的一半大小，如是就直接在老生代上分配；</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 默认情况下的垃圾回收规则：</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、在回收前PS GC会先检测之前每次PS GC时，晋升到老生代的平均大小是否大于老生代的剩余空间，如大于则直接触发full GC；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、在回收后，也会按照上面的规则进行检测。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 默认情况下的新生代对象晋升到老生代的规则：<br>&nbsp;&nbsp;&nbsp;&nbsp; 1、经历多次minor gc仍存活的对象，可通过以下参数来控制：AlwaysTenure，默认false，表示只要minor GC时存活，就晋升到老生代；NeverTenure，默认false，表示永不晋升到老生代；上面两个都没设置的情冴下，如UseAdaptiveSizePolicy，启动时以InitialTenuringThreshold值作为存活次数的阈值，在每次ps gc后会动态调整，如不使用UseAdaptiveSizePolicy，则以MaxTenuringThreshold为准。<br>&nbsp;&nbsp;&nbsp;&nbsp; 2、to space放不下的，直接放入老生代。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; 在回收后，如UseAdaptiveSizePolicy，PS GC会根据运行状态动态调整eden、to以及TenuringThreshold的大小。如果不希望动态调整可设置-XX:-UseAdaptiveSizePolicy。如希望跟踪每次的变化情况，可在启劢参数上增加： PrintAdaptiveSizePolicy。</p> <p>二、老生代可用GC</p> <p>1、串行GC(Serial Copying)：client方式下默认GC方式，可通过-XX:+UseSerialGC强制指定。</p> <p>&nbsp;&nbsp;&nbsp; 触发机制汇总：<br>&nbsp;&nbsp; 1）old gen空间不足；<br>&nbsp;&nbsp; 2）perm gen空间不足；<br>&nbsp;&nbsp; 3）minor gc时的悲观策略；<br>&nbsp;&nbsp; 4）minor GC后在eden上分配内存仍然失败；<br>&nbsp;&nbsp; 5）执行heap dump时；<br>&nbsp;&nbsp; 6）外部调用System.gc，可通过-XX:+DisableExplicitGC来禁止。</p> <p>2、并行回收GC(Parallel Scavenge)： server模式下默认GC方式，可通过-XX:+UseParallelGC强制指定； 并行的线程数为当cpu core&lt;=8 ? cpu core : 3+(cpu core*5)/8或通过-XX:ParallelGCThreads=x来强制指定。如ScavengeBeforeFullGC为true（默认值），则先执行minor GC。</p> <p>3、并行Compacting：可通过-XX:+UseParallelOldGC强制指定。</p> <p>4、并发CMS：可通过-XX:+UseConcMarkSweepGC来强制指定。并发的线程数默认为:( 并行GC线程数+3)/4，也可通过ParallelCMSThreads指定。</p> <p>&nbsp;&nbsp;&nbsp; 触发机制：<br>&nbsp;&nbsp;&nbsp; 1、当老生代空间的使用到达一定比率时触发；</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; Hotspot V 1.6中默认为65%，可通过PrintCMSInitiationStatistics（此参数在V 1.5中不能用）来查看这个值到底是多少；可通过CMSInitiatingOccupancyFraction来强制指定，默认值并不是赋值在了这个值上，是根据如下公式计算出来的： ((100 - MinHeapFreeRatio) +(double)(CMSTriggerRatio * MinHeapFreeRatio) / 100.0)/ 100.0; 其中,MinHeapFreeRatio默认值： 40&nbsp;&nbsp; CMSTriggerRatio默认值： 80。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; 2、当perm gen采用CMS收集且空间使用到一定比率时触发；</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; perm gen采用CMS收集需设置：-XX:+CMSClassUnloadingEnabled&nbsp;&nbsp; Hotspot V 1.6中默认为65%；可通过CMSInitiatingPermOccupancyFraction来强制指定，同样，它是根据如下公式计算出来的：((100 - MinHeapFreeRatio) +(double)(CMSTriggerPermRatio* MinHeapFreeRatio) / 100.0)/ 100.0; 其中，MinHeapFreeRatio默认值： 40&nbsp;&nbsp;&nbsp; CMSTriggerPermRatio默认值： 80。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3、Hotspot根据成本计算决定是否需要执行CMS GC；可通过-XX:+UseCMSInitiatingOccupancyOnly来去掉这个动态执行的策略。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4、外部调用了System.gc，且设置了ExplicitGCInvokesConcurrent；需要注意，在hotspot 6中，在这种情况下如应用同时使用了NIO，可能会出现bug。</p> <p><strong>6、GC组合</strong></p> <p>1）默认GC组合</p> <p><a href="http://www.blogjava.net/images/blogjava_net/chhbjh/Windows-Live-Writer/2d08114b62d1_AA6A/image_9.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.blogjava.net/images/blogjava_net/chhbjh/Windows-Live-Writer/2d08114b62d1_AA6A/image_thumb_3.png" width="638" height="125"></a></p> <p>2）可选的GC组合</p> <p><a href="http://www.blogjava.net/images/blogjava_net/chhbjh/Windows-Live-Writer/2d08114b62d1_AA6A/image_11.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.blogjava.net/images/blogjava_net/chhbjh/Windows-Live-Writer/2d08114b62d1_AA6A/image_thumb_4.png" width="638" height="441"></a></p> <p><strong>7、GC监测</strong></p> <p>1）jstat –gcutil [pid] [intervel] [count]<br>2）-verbose:gc // 可以辅助输出一些详细的GC信息；-XX:+PrintGCDetails // 输出GC详细信息；-XX:+PrintGCApplicationStoppedTime // 输出GC造成应用暂停的时间<br>-XX:+PrintGCDateStamps // GC发生的时间信息；-XX:+PrintHeapAtGC // 在GC前后输出堆中各个区域的大小；-Xloggc:[file] // 将GC信息输出到单独的文件中，建议都加上，这个消耗不大，而且对查问题和调优有很大的帮助。gc的日志拿下来后可使用GCLogViewer或gchisto进行分析。<br>3）图形化的情况下可直接用jvisualvm进行分析。</p> <p>4）查看内存的消耗状况</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （1）长期消耗，可以直接dump，然后MAT(内存分析工具)查看即可</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （2）短期消耗，图形界面情况下，可使用jvisualvm的memory profiler或jprofiler。</p> <p><strong>8、系统调优方法</strong></p> <p><strong>步骤：1、评估现状 2、设定目标 3、尝试调优 4、衡量调优 5、细微调整</strong></p> <p><strong>设定目标：</strong></p> <p>1）降低Full GC的执行频率？<br>2）降低Full GC的消耗时间？<br>3）降低Full GC所造成的应用停顿时间？<br>4）降低Minor GC执行频率？<br>5）降低Minor GC消耗时间？<br>例如某系统的GC调优目标：降低Full GC执行频率的同时，尽可能降低minor GC的执行频率、消耗时间以及GC对应用造成的停顿时间。</p> <p><strong>衡量调优：</strong></p> <p>1、衡量工具<br>1）打印GC日志信息：-XX:+PrintGCDetails –XX:+PrintGCApplicationStoppedTime -Xloggc: {文件名}&nbsp; -XX:+PrintGCTimeStamps<br>2）jmap：（由于每个版本jvm的默认值可能会有改变，建议还是用jmap首先观察下目前每个代的内存大小、GC方式） <br>3）运行状况监测工具：jstat、jvisualvm、sar 、gclogviewer</p> <p>2、应收集的信息<br>1）minor gc的执行频率；full gc的执行频率，每次GC耗时多少？<br>2）高峰期什么状况？<br>3）minor gc回收的效果如何？survivor的消耗状况如何，每次有多少对象会进入老生代？<br>4）full gc回收的效果如何？（简单的<strong>memory leak</strong>判断方法）<br>5）系统的load、cpu消耗、qps or tps、响应时间</p> <p>QPS每秒查询率：是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。在因特网上，作为域名服务器的机器性能经常用每秒查询率来衡量。对应fetches/sec，即每秒的响应请求数，也即是最大吞吐能力。<br>TPS(Transaction Per Second)：每秒钟系统能够处理的交易或事务的数量。</p> <p><strong>尝试调优：</strong></p> <p>注意Java RMI的定时GC触发机制，可通过：-XX:+DisableExplicitGC来禁止或通过 -Dsun.rmi.dgc.server.gcInterval=3600000来控制触发的时间。</p> <p>1）降低Full GC执行频率 – 通常瓶颈<br>老生代本身占用的内存空间就一直偏高，所以只要稍微放点对象到老生代，就full GC了；<br>通常原因：系统缓存的东西太多；<br>例如：使用oracle 10g驱动时preparedstatement cache太大；<br>查找办法：现执行Dump然后再进行MAT分析；</p> <p>（1）Minor GC后总是有对象不断的进入老生代，导致老生代不断的满<br>通常原因：Survivor太小了<br>系统表现：系统响应太慢、请求量太大、每次请求分配的内存太多、分配的对象太大...<br>查找办法：分析两次minor GC之间到底哪些地方分配了内存；<br>利用jstat观察Survivor的消耗状况，-XX:PrintHeapAtGC，输出GC前后的详细信息；<br>对于系统响应慢可以采用系统优化，不是GC优化的内容；</p> <p>（2）老生代的内存占用一直偏高<br>调优方法：① 扩大老生代的大小（减少新生代的大小或调大heap的 大小）；<br>减少new注意对minor gc的影响并且同时有可能造成full gc还是严重；<br>调大heap注意full gc的时间的延长，cpu够强悍嘛，os是32 bit的吗？<br>② 程序优化（去掉一些不必要的缓存）</p> <p>（3）Minor GC后总是有对象不断的进入老生代<br>前提：这些进入老生代的对象在full GC时大部分都会被回收<br>调优方法：<br>① 降低Minor GC的执行频率；<br>② 让对象尽量在Minor GC中就被回收掉：增大Eden区、增大survivor、增大TenuringThreshold；注意这些可能会造成minor gc执行频繁；<br>③ 切换成CMS GC：老生代还没有满就回收掉，从而降低Full GC触发的可能性；<br>④ 程序优化：提升响应速度、降低每次请求分配的内存、</p> <p>（4）降低单次Full GC的执行时间<br>通常原因：老生代太大了...<br>调优方法：1）是并行GC吗？&nbsp;&nbsp; 2）升级CPU&nbsp; 3）减小Heap或老生代</p> <p>（5）降低Minor GC执行频率<br>通常原因：每次请求分配的内存多、请求量大<br>通常办法：1）扩大heap、扩大新生代、扩大eden。注意点：降低每次请求分配的内存；横向增加机器的数量分担请求的数量。</p> <p>（6）降低Minor GC执行时间<br>通常原因：新生代太大了，响应速度太慢了，导致每次Minor GC时存活的对象多<br>通常办法：1）减小点新生代吧；2）增加CPU的数量、升级CPU的配置；加快系统的响应速度</p> <p><strong>细微调整：</strong></p> <p>首先需要了解以下情况：</p> <p>① 当响应速度下降到多少或请求量上涨到多少时，系统会宕掉？</p> <p>② 参数调整后系统多久会执行一次Minor GC，多久会执行一次Full GC，高峰期会如何？</p> <p>需要计算的量：</p> <p>①每次请求平均需要分配多少内存？系统的平均响应时间是多少呢？请求量是多少、多常时间执行一次Minor GC、Full GC？</p> <p>②现有参数下，应该是多久一次Minor GC、Full GC，对比真实状况，做一定的调整；</p> <p>必杀技：提升响应速度、降低每次请求分配的内存？</p> <p><strong>9、系统调优举例</strong></p> <p>&nbsp;&nbsp;&nbsp;&nbsp; 现象：1、系统响应速度大概为100ms；2、当系统QPS增长到40时，机器每隔5秒就执行一次minor gc，每隔3分钟就执行一次full gc，并且很快就一直full GC了；4、每次Full gc后旧生代大概会消耗400M，有点多了。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; 解决方案：解决Full GC次数过多的问题</p> <p>&nbsp;&nbsp;&nbsp; （1）降低响应时间或请求次数，这个需要重构，比较麻烦；——这个是终极方法，往往能够顺利的解决问题，因为大部分的问题均是由程序自身造成的。</p> <p>&nbsp;&nbsp;&nbsp; （2）减少老生代内存的消耗，比较靠谱；——可以通过分析Dump文件（jmap dump），并利用MAT查找内存消耗的原因，从而发现程序中造成老生代内存消耗的原因。</p> <p>&nbsp;&nbsp;&nbsp; （3）减少每次请求的内存的消耗，貌似比较靠谱；——这个是海市蜃楼，没有太好的办法。</p> <p>&nbsp;&nbsp;&nbsp; （4）降低GC造成的应用暂停的时间——可以采用CMS GS垃圾回收器。参数设置如下：</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; -Xms1536m -Xmx1536m -Xmn700m -XX:SurvivorRatio=7 -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection </p> <p>&nbsp;&nbsp;&nbsp;&nbsp; -XX:CMSMaxAbortablePrecleanTime=1000 -XX:+CMSClassUnloadingEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:+DisableExplicitGC</p> <p>&nbsp;&nbsp;&nbsp; （5）减少每次minor gc晋升到old的对象。可选方法：1） 调大新生代。2）调大Survivor。3）调大TenuringThreshold。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 调大Survivor：当前采用PS GC，Survivor space会被动态调整。由于调整幅度很小，导致了经常有对象直接转移到了老生代；于是禁止Survivor区的动态调整了，-XX:-UseAdaptiveSizePolicy，并计算Survivor Space需要的大小，于是继续观察，并做微调…。最终将Full GC推迟到2小时1次。</p> <p><strong>10、垃圾回收的实现原理</strong></p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 内存回收的实现方法：1）引用计数：不适合复杂对象的引用关系，尤其是循环依赖的场景。2）有向图Tracing：适合于复杂对象的引用关系场景，Hotspot采用这种。常用算法：Copying、Mark-Sweep、Mark-Compact。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hotspot从root set开始扫描有引用的对象并对Reference类型的对象进行特殊处理。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 以下是Root Set的列表：1）当前正在执行的线程；2）全局/静态变量；3）JVM Handles；4）JNI 【 Java Native Interface 】Handles；</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 另外：minor GC只扫描新生代，当老生代的对象引用了新生代的对象时，会采用如下的处理方式：在给对象赋引用时，会经过一个write barrier的过程，以便检查是否有老生代引用新生代对象的情况，如有则记录到remember set中。并在minor gc时，remember set指向的新生代对象也作为root set。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; <strong>新生代串行GC(Serial Copying)：</strong> </p> <p>&nbsp;&nbsp;&nbsp;&nbsp; 新生代串行GC(Serial Copying)完整内存的分配策略：</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; 1）首先在TLAB（本地线程分配缓冲区）上尝试分配；<br>&nbsp;&nbsp;&nbsp;&nbsp; 2）检查是否需要在新生代上分配，如需要分配的大小小于PretenureSizeThreshold，则在eden区上进行分配，分配成功则返回；分配失败则继续；<br>&nbsp;&nbsp;&nbsp;&nbsp; 3）检查是否需要尝试在老生代上分配，如需要，则遍历所有代并检查是否可在该代上分配，如可以则进行分配；如不需要在老生代上尝试分配，则继续；<br>&nbsp;&nbsp;&nbsp;&nbsp; 4）根据策略决定执行新生代GC或Full GC，执行full gc时不清除soft Ref；<br>&nbsp;&nbsp;&nbsp;&nbsp; 5）如需要分配的大小大于PretenureSizeThreshold，尝试在老生代上分配，否则尝试在新生代上分配；<br>&nbsp;&nbsp;&nbsp;&nbsp; 6）尝试扩大堆并分配；<br>&nbsp;&nbsp;&nbsp;&nbsp; 7）执行full gc，并清除所有soft Ref，按步骤5继续尝试分配。&nbsp;&nbsp; </p> <p>&nbsp;&nbsp;&nbsp;&nbsp; 新生代串行GC(Serial Copying)完整内存回收策略<br>&nbsp;&nbsp;&nbsp;&nbsp; 1）检查to是否为空，不为空返回false；<br>&nbsp;&nbsp;&nbsp;&nbsp; 2）检查老生代剩余空间是否大于当前eden+from已用的大小，如大于则返回true，如小于且HandlePromotionFailure为true，则检查剩余空间是否大于之前每次minor gc晋级到老生代的平均大小，如大于返回true，如小于返回false。<br>&nbsp;&nbsp;&nbsp;&nbsp; 3）如上面的结果为false，则执行full gc；如上面的结果为true，执行下面的步骤；<br>&nbsp;&nbsp;&nbsp;&nbsp; 4）扫描引用关系，将活的对象copy到to space，如对象在minor gc中的存活次数超过tenuring_threshold或分配失败，则往老生代复制，如仍然复制失败，则取决于HandlePromotionFailure，如不需要处理，直接抛出OOM，并退出vm，如需处理，则保持这些新生代对象不动；</p> <p>&nbsp;&nbsp;&nbsp; <strong>新生代可用GC-PS</strong></p> <p>&nbsp;&nbsp;&nbsp; 完整内存分配策略<br>&nbsp;&nbsp;&nbsp; 1）先在TLAB上分配，分配失败则直接在eden上分配；<br>&nbsp;&nbsp;&nbsp; 2）当eden上分配失败时，检查需要分配的大小是否 &gt;= eden space的一半，如是，则直接在老生代分配；<br>&nbsp;&nbsp;&nbsp; 3）如分配仍然失败，且gc已超过频率，则抛出OOM；<br>&nbsp;&nbsp;&nbsp; 4）进入基本分配策略失败的模式；<br>&nbsp;&nbsp;&nbsp; 5）执行PS GC，在eden上分配；<br>&nbsp;&nbsp;&nbsp; 6）执行非最大压缩的full gc，在eden上分配；<br>&nbsp;&nbsp;&nbsp; 7）在旧生代上分配；<br>&nbsp;&nbsp;&nbsp; 8）执行最大压缩full gc，在eden上分配；<br>&nbsp;&nbsp;&nbsp; 9）在旧生代上分配；<br>&nbsp;&nbsp;&nbsp; 10）如还失败，回到2。</p> <p>&nbsp;&nbsp; 最悲惨的情况，分配触发多次PS GC和多次Full GC，直到OOM。</p> <p>&nbsp;&nbsp; 完整内存回收策略<br>&nbsp;&nbsp; 1）如gc所执行的时间超过，直接结束；<br>&nbsp;&nbsp; 2）先调用invoke_nopolicy<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.1 先检查是不是要尝试scavenge；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.1.1 to space必须为空，如不为空，则返回false；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.1.2 获取之前所有minor gc晋级到old的平均大小，并对比目前eden+from已使用的大小，取更小的一个值，如老生代剩余空间小于此值，则返回false，如大于则返回true；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.2 如不需要尝试scavenge，则返回false，否则继续；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.3 多线程扫描活的对象，并基亍copying算法回收，回收时相应的晋升对象到旧生代；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.4 如UseAdaptiveSizePolicy，那么重新计算to space和tenuringThreshold的值，并调整。<br>&nbsp;&nbsp; 3）如invoke_nopolicy返回的是false，或之前所有minor gc晋级到老生代的平均大小 &gt; 旧生代的剩余空间，那么继续下面的步骤，否则结束；<br>&nbsp;&nbsp; 4）如UseParallelOldGC，则执行PSParallelCompact，如不是UseParallelOldGC，则执行PSMarkSweep。</p> <p>&nbsp;&nbsp;&nbsp; <strong>老生代并行CMS GC：</strong></p> <p><strong>&nbsp;&nbsp;&nbsp; 优缺点：</strong></p> <p><strong>&nbsp;&nbsp;&nbsp; </strong>1） 大部分时候和应用并发进行，因此只会造成很短的暂停时间；<br>&nbsp;&nbsp;&nbsp; 2）浮动垃圾，没办法，所以内存空间要稍微大一点；<br>&nbsp;&nbsp;&nbsp; 3）内存碎片，-XX:+UseCMSCompactAtFullCollection 来解决；<br>&nbsp;&nbsp;&nbsp; 4） 争抢CPU，这GC方式就这样；<br>&nbsp;&nbsp;&nbsp; 5）多次remark，所以总的gc时间会比并行的长；<br>&nbsp;&nbsp;&nbsp; 6）内存分配，free list方式，so性能稍差，对minor GC会有一点影响；<br>&nbsp;&nbsp;&nbsp; 7）和应用并发，有可能分配和回收同时，产生竞争，引入了锁，JVM分配优先。</p> <p><strong>11、TLAB的解释</strong></p> <p>&nbsp;&nbsp;&nbsp;&nbsp; 堆内的对象数据是各个线程所共享的，所以当在堆内创建新的对象时，就需要进行锁操作。锁操作是比较耗时，因此JVM为每个线在堆上分配了一块“自留地”——TLAB(全称是Thread Local Allocation Buffer)，位于堆内存的新生代，也就是Eden区。每个线程在创建新的对象时，会首先尝试在自己的TLAB里进行分配，如果成功就返回，失败了再到共享的Eden区里去申请空间。在线程自己的TLAB区域创建对象失败一般有两个原因：一是对象太大，二是自己的TLAB区剩余空间不够。通常默认的TLAB区域大小是Eden区域的1%，当然也可以手工进行调整，对应的JVM参数是-XX:TLABWasteTargetPercent。  <p>参考文献：  <p>1、Sun JDK 1.6 GC（Garbage Collector）&nbsp; 作者：毕玄</p><img src ="http://www.blogjava.net/chhbjh/aggbug/368936.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chhbjh/" target="_blank">阳光咖啡</a> 2012-01-28 21:41 <a href="http://www.blogjava.net/chhbjh/archive/2012/01/28/368936.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大型电子政务项目问题总结</title><link>http://www.blogjava.net/chhbjh/archive/2011/12/09/360282.html</link><dc:creator>阳光咖啡</dc:creator><author>阳光咖啡</author><pubDate>Fri, 09 Dec 2011 05:02:00 GMT</pubDate><guid>http://www.blogjava.net/chhbjh/archive/2011/12/09/360282.html</guid><wfw:comment>http://www.blogjava.net/chhbjh/comments/360282.html</wfw:comment><comments>http://www.blogjava.net/chhbjh/archive/2011/12/09/360282.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/chhbjh/comments/commentRss/360282.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chhbjh/services/trackbacks/360282.html</trackback:ping><description><![CDATA[<p><strong>一、项目管理方面</strong>  </p><p>1、业主、总集成商、监理单位、承建单位、产品供货单位的沟通协调问题。首先，在与业主的沟通方面，最初较为混乱，主要原因是没有形成统一的沟通结构与机制，在最初的近三个月的时间里导致项目推进速度非常缓慢。经与业主单位沟通，制定了工程的沟通方案，建立了沟通组织结构。主要内容是在业主单位方面建立了项目实施办，项目实施办对部领导组成的项目办负责，明确了项目办与实施办的责任，由实施办协调信息中心各处室共同推进项目工作；并且在信息中心内部推行&#8220;承诺书&#8221;也就是各处室均对工程的建设内容进行承诺并与绩效挂钩。其次，总集成商、总监理商与实施办沟通，实施办与相关处室沟通，承建商与产品供货单位在技术上接受总集成商的指导与约束；在流程的规范性上接受总监理商的指导与约束；在业务上接受信息中心负责处室的约束。由此，通过沟通方案建立与推行，项目的沟通协调方面才进入了正轨，项目的推进速度明显加快。  </p><p>2、用户单位对项目的支持度等方面的问题。某些用户单位对所建设的项目并没有强烈的需求，持可有可无或最好没有的态度，但在工程的初设中这些项目又是必须建设的内容。因此，在项目的实施的过程中，这写用户单位对项目的各项工作均持消极态度，使得项目无法正常推进。例如，有些用户单位不组织本单位人员配合需求调研，不组织下属各省级单位进行系统试运行，不组织本单位人员进行用户测试等。对于这些问题往往系统承建商方面已无法推动，需要通过实施办与项目办层面与用户单位沟通协商一致后才能继续开展工作。  </p><p>3、部本级项目与省级项目的协调推进问题。由于在工程的可研中包含各省的项目建设，各省建设的进度对整体项目的最终验收具有制约作用。目前，各省的建设情况各不一致，有的已经完成，有的正在建设过程中，有的资金尚未批复。。。  </p><p><strong>二、技术架构方面</strong>  </p><p>1、应用系统部署架构问题。在09年底的时候，在应用系统部署架构出现了一个&#8220;互联网区应用系统访问Oracle RAC数据库时断时续问题&#8221;，此问题先后持续了4到5个月，制约了项目的建设进度（期间采用了其他方式，尽量减少了损失）。原因1，在进行整体应用系统部署架构设计时，尚未进行相应产品的招标，因此无法明确具体的产品（各产品在具体的实现层面有差别，这些差别可能影响部署架构的实现）。原因2，各厂商均具有专业领域的知识背景，但对各知识领域之间的把握较少，因此很可能在边缘领域出现问题。原因3，由于本项目为大型的电子政务项目，涉及的专业知识领域和技术手段非常繁杂，在设计与测试过程中非常困难。在实施办与总集的总体协调下，经过多次的评审与大量的测试，对应用系统部署架构进行了调整，使问题成功解决。此类问题的解决方法是由总集成商牵头，召集相关的承建单位，如网络集成商、安全集成商、数据库提供商。。。共同讨论分析，制定问题的排查方案，并按照方案查找问题的原因。待问题的原因查找清楚后，再由总集成商召集相关承建商共同讨论提出解决方法，经实施办审核通过（如重大技术问题可由实施办召集专家进行评审确定）。  </p><p>2、部分系统试运行阶段性能低下与生产环境问题排查困难等。一方面，工程所用到的技术非常复杂，采用了大量的设备，如 Oralce RAC集群，存储，IBM小型机、负载均衡集群等，此种环境很难有一个企业（如承建单位或第三方测试单位）复制。因此，无论是承建单位还是第三方测试单位所进行的测试均无法完全反映生产环境下的性能指标。另一方面，此种生产环境也是初次搭建，其技术可行性只停留在理论层面，期间的技术细节无法完全在设计阶段考虑到，只能通过一段时间的系统试运行才能够暴露与完善。当然，如果能够在系统进行初步设计时，能够考虑搭建一套与生产环境完全或基本一致的测试环境，此问题将能够很方便的进行解决，也就是可以在测试环境中进行应用系统的压力测试与问题排查，待系统稳定后并满足用户要求时，再将系统迁移至正式的生产环境中，这种方式可以最大程度的保持生产环境的稳定性。</p><img src ="http://www.blogjava.net/chhbjh/aggbug/360282.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chhbjh/" target="_blank">阳光咖啡</a> 2011-12-09 13:02 <a href="http://www.blogjava.net/chhbjh/archive/2011/12/09/360282.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于并发用户数、系统用户数和同时在线用户数等概念的辨析</title><link>http://www.blogjava.net/chhbjh/archive/2011/12/09/365952.html</link><dc:creator>阳光咖啡</dc:creator><author>阳光咖啡</author><pubDate>Fri, 09 Dec 2011 04:46:00 GMT</pubDate><guid>http://www.blogjava.net/chhbjh/archive/2011/12/09/365952.html</guid><wfw:comment>http://www.blogjava.net/chhbjh/comments/365952.html</wfw:comment><comments>http://www.blogjava.net/chhbjh/archive/2011/12/09/365952.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chhbjh/comments/commentRss/365952.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chhbjh/services/trackbacks/365952.html</trackback:ping><description><![CDATA[<blockquote> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 以下内容结合了其他网友发表的内容，首先再次表示感谢。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 假设一个系统有2000个使用者（对于一般的企业系统，这个概念比较简单，就是指数据库中的用户总数，但对于网站型的系统而言，相对较为复杂，一般为注册用户和游客的总和），也就是说，该系统的用户总数是2000名，这个概念表示的是&#8220;系统用户数&#8221;。如果该系统具有&#8220; 在线统计&#8221;功能，该功能一般用于记录系统中所有已经登录的用户（当然如果有一些系统功能同时也提供给未登录的用户使用，那么未登录的当前使用者也应记录进来），如果根据此统计结果得到最高峰时有500人在线，那么这个500就是所说的&#8220;同时在线用户数&#8221;。 <br />&nbsp;&nbsp;&nbsp; 根据对业务并发用户数的定义，这500就是整个系统使用时最大的业务并发用户数。当然，500这个数值只是表明在最高峰时刻有500个用户登录了系统，并不表示实际服务器承受的压力。因为服务器承受的压力还与具体的用户访问模式相关。例如，考察具体的某一个时间点，在这500个&#8220;同时在线用户数&#8221;中，其中40%的用户在较有兴致地看系统公告（注意：&#8220;看&#8221;这个动作是不会对服务端产生任何负担的），20%的用户在填写复杂的表格（对用户填写的表格来说，只有在&#8220;提交&#8221;的时刻才会向服务端发送请求，填写过程是不对服务端构成压力的），20%部分用户在发呆（也就是什么也没有做），剩下的 20%用户在不停地从一个页面跳转到另一个页面&#8212;&#8212;在这种场景下，可以说，只有20%的用户真正对服务器构成了压力。因此，从上面的例子中可以看出，服务器实际承受的压力不只取决于业务并发用户数，还取决于用户的业务场景。 <br />在实际的性能测试工作中，<font color="#ff0000">测试人员一般比较关心的是业务并发用户数</font>，也就是从业务角度关注究竟应该设置多少个并发数比较合理，因此，在后面的讨论中，也是主要针对业务并发用户数进行讨论，<font color="#ff0000">而且为了方便，直接将业务并发用户数称为并发用户数</font><font color="#ff0000">。</font> <br />（1） 计算平均的并发用户数： C = nL/T <br />（2） 并发用户数峰值： C&#8217; &#8776; C+3根号C <br />公式（1）中C是平均的并发用户数；n是login session的数量；L是login session的平均长度；T指考察的时间段长度。 <br />公式（2）给出了并发用户数峰值的计算方式，其中C&#8217;指并发用户数的峰值，C就是公式（1）中得到的平均的并发用户数。该公式的得出是假设用户的login session产生符合泊松分布而估算得到的。 <br />实例： <br />假设有一个OA系统，该系统有3000个用户，平均每天大约有400个用户要访问该系统，对一个典型用户来说，一天之内用户从登录到退出该系统的平均时间为4小时，在一天的时间内，用户只在8小时内使用该系统。 <br />则根据公式（1）和公式（2），可以得到： <br />C = 400*4/8 = 200 <br />C&#8217;&#8776;200+3*根号200 = 242</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 以下是测试所需的一些常用公式，仅供参考</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F=VU * R / T&nbsp;&nbsp; R = T / TS</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 其中F为吞吐量，VU表示虚拟用户个数，R表示每个虚拟用户发出的请求数，T表示性能测试所用的时间，TS为用户思考时间 。</p></blockquote><img src ="http://www.blogjava.net/chhbjh/aggbug/365952.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chhbjh/" target="_blank">阳光咖啡</a> 2011-12-09 12:46 <a href="http://www.blogjava.net/chhbjh/archive/2011/12/09/365952.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Uml2随笔</title><link>http://www.blogjava.net/chhbjh/archive/2006/03/31/38510.html</link><dc:creator>阳光咖啡</dc:creator><author>阳光咖啡</author><pubDate>Fri, 31 Mar 2006 09:09:00 GMT</pubDate><guid>http://www.blogjava.net/chhbjh/archive/2006/03/31/38510.html</guid><wfw:comment>http://www.blogjava.net/chhbjh/comments/38510.html</wfw:comment><comments>http://www.blogjava.net/chhbjh/archive/2006/03/31/38510.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chhbjh/comments/commentRss/38510.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chhbjh/services/trackbacks/38510.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<br />   UML随想及UML2.0的图分类：<br />   使用</span>
				<span lang="EN-US">UML</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">上的差异共有以下三种：</span>
				<span lang="EN-US">1</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、分别将</span>
				<span lang="EN-US">UML</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">视为草稿、蓝图与程序语言三种不同用法。</span>
				<span lang="EN-US">2</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、以软件观点和概念性观点来看待</span>
				<span lang="EN-US">UML</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span>
				<span lang="EN-US">3</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span>
				<span lang="EN-US">UML</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的本质在于图或超模型。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt">
				<span lang="EN-US">1</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、搭配草稿、蓝图两种用法的步骤为</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; tab-stops: list 39.0pt; mso-list: l0 level1 lfo1">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">1）<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">先画出</span>
				<span lang="EN-US">UML</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">草稿</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; tab-stops: list 39.0pt; mso-list: l0 level1 lfo1">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">2）<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以</span>
				<span lang="EN-US">CASE</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">工具用正向工程转出程序码大纲</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; tab-stops: list 39.0pt; mso-list: l0 level1 lfo1">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">3）<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">修改程序码</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; tab-stops: list 39.0pt; mso-list: l0 level1 lfo1">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">4）<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">定期从程序码已</span>
				<span lang="EN-US">CASE</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">工具用反向工程转出</span>
				<span lang="EN-US">UML</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设计模型</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将</span>
				<span lang="EN-US">UML</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">视为草稿是在谈</span>
				<span lang="EN-US">[</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">选择性</span>
				<span lang="EN-US">]</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。选择主要的模块进行讨论。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将</span>
				<span lang="EN-US">UML</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">视为蓝图是在谈</span>
				<span lang="EN-US">[</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">完整性</span>
				<span lang="EN-US">]</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这种做法可以用在所有</span>
				<span lang="EN-US">[</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">细节</span>
				<span lang="EN-US">]</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的工作上，也可以针对特定的部分化出蓝图。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模型驱动开发架构（</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span lang="EN-US" style="FONT-FAMILY: TimesNewRoman; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: TimesNewRoman; mso-fareast-font-family: ArialUnicodeMS; mso-font-kerning: 0pt">Model Driven Architecture</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-FAMILY: ArialUnicodeMS; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: ArialUnicodeMS; mso-font-kerning: 0pt">，</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span lang="EN-US" style="FONT-FAMILY: TimesNewRoman; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: TimesNewRoman; mso-fareast-font-family: ArialUnicodeMS; mso-font-kerning: 0pt">MDA</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）：</span>
						<span lang="EN-US">MDA</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将</span>
						<span lang="EN-US">UML</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">视为程序语言的标准用法。</span>
				</b>
				<span lang="EN-US">MDA</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将开发分为两个主要部分，模型建立者会负责产生于平台无关的模型</span>
				<span style="FONT-FAMILY: ArialUnicodeMS; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: ArialUnicodeMS; mso-font-kerning: 0pt">（</span>
				<span lang="EN-US" style="FONT-FAMILY: TimesNewRoman; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: TimesNewRoman; mso-fareast-font-family: ArialUnicodeMS; mso-font-kerning: 0pt">Platform Independent Model</span>
				<span style="FONT-FAMILY: ArialUnicodeMS; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: ArialUnicodeMS; mso-font-kerning: 0pt">，</span>
				<span lang="EN-US" style="FONT-FAMILY: TimesNewRoman; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: TimesNewRoman; mso-fareast-font-family: ArialUnicodeMS; mso-font-kerning: 0pt">PIM</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">），</span>
				<span lang="EN-US">PIM</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">代表与任何与特定格式无关的</span>
				<span lang="EN-US">UML</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模型。然后工具可以把</span>
				<span lang="EN-US">PIM</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">转换为平台特有模型（</span>
				<span lang="EN-US">PSM</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">），</span>
				<span lang="EN-US">PSM</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是在某个特定执行环境之上的模型，其他工具可以将</span>
				<span lang="EN-US">PSM</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">转换为某个平台之上的程序码。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US">UML</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的创造者认为</span>
				<span lang="EN-US">UML</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的本质在于超模型，图仅仅是超模型的展现而已。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">个人推荐将<span lang="EN-US">UML</span>作为草稿的用法，<span lang="EN-US"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">UML2.0</span>
				<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">中的图共有如下<span lang="EN-US">11</span>种：<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; tab-stops: list 39.0pt; mso-list: l1 level1 lfo2; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体">
						<span style="mso-list: Ignore">1、<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">活动图（<span lang="EN-US">activity diagram</span>）<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; tab-stops: list 39.0pt; mso-list: l1 level1 lfo2; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">
						<span style="mso-list: Ignore">2、<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">类图（<span lang="EN-US">Class diagram</span>）</span>
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: ArialUnicodeMS; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; tab-stops: list 39.0pt; mso-list: l1 level1 lfo2; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">
						<span style="mso-list: Ignore">3、<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: ArialUnicodeMS; mso-font-kerning: 0pt">合作图（</span>
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: TimesNewRoman; mso-font-kerning: 0pt">communicationdiagram diagram</span>
				<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: ArialUnicodeMS; mso-font-kerning: 0pt">）：对象件的互动情形，焦点在连接关系上</span>
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: TimesNewRoman; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; tab-stops: list 39.0pt; mso-list: l1 level1 lfo2; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">
						<span style="mso-list: Ignore">4、<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: ArialUnicodeMS; mso-font-kerning: 0pt">元件图（<span lang="EN-US">component diagram</span>）元件结构与连接关系</span>
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: TimesNewRoman; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; tab-stops: list 39.0pt; mso-list: l1 level1 lfo2; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">
						<span style="mso-list: Ignore">5、<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: ArialUnicodeMS; mso-font-kerning: 0pt">合成结构（<span lang="EN-US">composite structure</span>）类别在执行期的合成情形（<span lang="EN-US">UML2</span></span>
				<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: TimesNewRoman; mso-font-kerning: 0pt">新增</span>
				<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: ArialUnicodeMS; mso-font-kerning: 0pt">）</span>
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: TimesNewRoman; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; tab-stops: list 39.0pt; mso-list: l1 level1 lfo2; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">
						<span style="mso-list: Ignore">6、<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: ArialUnicodeMS; mso-font-kerning: 0pt">配置图（<span lang="EN-US">deployment diagram</span>）将工作成果配置到节点上</span>
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: TimesNewRoman; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; tab-stops: list 39.0pt; mso-list: l1 level1 lfo2; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">
						<span style="mso-list: Ignore">7、<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: ArialUnicodeMS; mso-font-kerning: 0pt">互动概图（<span lang="EN-US">interaction overview diagram</span>）混合时序图与活动图两者（<span lang="EN-US">UML2</span>新增）</span>
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: TimesNewRoman; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; tab-stops: list 39.0pt; mso-list: l1 level1 lfo2; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">
						<span style="mso-list: Ignore">8、<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: ArialUnicodeMS; mso-font-kerning: 0pt">对象图（<span lang="EN-US">object diagram</span>）</span>
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: TimesNewRoman; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; tab-stops: list 39.0pt; mso-list: l1 level1 lfo2; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">
						<span style="mso-list: Ignore">9、<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: ArialUnicodeMS; mso-font-kerning: 0pt">套件图（<span lang="EN-US">package diagram</span>）编译器的阶层结构</span>
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: TimesNewRoman; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; tab-stops: list 39.0pt; mso-list: l1 level1 lfo2; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">
						<span style="mso-list: Ignore">10、<span style="FONT: 7pt 'Times New Roman'"> </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: ArialUnicodeMS; mso-font-kerning: 0pt">时序图（<span lang="EN-US">sequence diagram</span>）对象间的互动情形，焦点在信息的先后顺序。<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; tab-stops: list 39.0pt; mso-list: l1 level1 lfo2; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">
						<span style="mso-list: Ignore">11、<span style="FONT: 7pt 'Times New Roman'">              </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: TimesNewRoman; mso-font-kerning: 0pt">状态机图（<span lang="EN-US">state machine diagram</span>）说明事件在对象中的生命力，如何改变状态<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; tab-stops: list 39.0pt; mso-list: l1 level1 lfo2; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">
						<span style="mso-list: Ignore">12、<span style="FONT: 7pt 'Times New Roman'">              </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: TimesNewRoman; mso-font-kerning: 0pt">时序图（<span lang="EN-US">timing diagrame</span>）对象间的互动情形（<span lang="EN-US">UML2</span>新增）<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; tab-stops: list 39.0pt; mso-list: l1 level1 lfo2; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">
						<span style="mso-list: Ignore">13、<span style="FONT: 7pt 'Times New Roman'">              </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: TimesNewRoman; mso-font-kerning: 0pt">用例图（<span lang="EN-US">use case diagrame</span>）说明使用者如何与系统进行交互<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p> </p>
<img src ="http://www.blogjava.net/chhbjh/aggbug/38510.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chhbjh/" target="_blank">阳光咖啡</a> 2006-03-31 17:09 <a href="http://www.blogjava.net/chhbjh/archive/2006/03/31/38510.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Apache Jakarta Log4J(学习笔记)</title><link>http://www.blogjava.net/chhbjh/archive/2005/09/07/12309.html</link><dc:creator>阳光咖啡</dc:creator><author>阳光咖啡</author><pubDate>Wed, 07 Sep 2005 04:22:00 GMT</pubDate><guid>http://www.blogjava.net/chhbjh/archive/2005/09/07/12309.html</guid><wfw:comment>http://www.blogjava.net/chhbjh/comments/12309.html</wfw:comment><comments>http://www.blogjava.net/chhbjh/archive/2005/09/07/12309.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chhbjh/comments/commentRss/12309.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chhbjh/services/trackbacks/12309.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Apache Jakarta Log4J(学习笔记)注:这些笔记来源于恨的网上资料,如与您的文章相冲突,望请见谅.一〉log4j的组件：记录器、存放器和布局下面分别讲述这几种组件：1〉记录器：log4j允许程序员定义多个记录器，每个记录器有自己的名字，记录器之间通过名字来表示隶属关系（或家族关系）。例如记录器a.b与记录器a.b.c是父子关系，而记录器a与记录器a.b.c是祖先与后代的...&nbsp;&nbsp;<a href='http://www.blogjava.net/chhbjh/archive/2005/09/07/12309.html'>阅读全文</a><img src ="http://www.blogjava.net/chhbjh/aggbug/12309.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chhbjh/" target="_blank">阳光咖啡</a> 2005-09-07 12:22 <a href="http://www.blogjava.net/chhbjh/archive/2005/09/07/12309.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Log学习笔记</title><link>http://www.blogjava.net/chhbjh/archive/2005/09/07/12305.html</link><dc:creator>阳光咖啡</dc:creator><author>阳光咖啡</author><pubDate>Wed, 07 Sep 2005 03:33:00 GMT</pubDate><guid>http://www.blogjava.net/chhbjh/archive/2005/09/07/12305.html</guid><wfw:comment>http://www.blogjava.net/chhbjh/comments/12305.html</wfw:comment><comments>http://www.blogjava.net/chhbjh/archive/2005/09/07/12305.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chhbjh/comments/commentRss/12305.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chhbjh/services/trackbacks/12305.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><B><SPAN lang=EN-US style="FONT-SIZE: 15pt; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt">Jakarta Commons Logging(JCL)</SPAN></B><B><SPAN style="FONT-SIZE: 15pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'; mso-bidi-font-size: 12.0pt">学习笔记</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 15pt; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.1pt; mso-char-indent-count: 2.0"><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">简介</SPAN></B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">：</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">JCL</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">提供一个日志接口，同时兼顾轻量级和不依赖于具体的日志实现工具。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.1pt; mso-char-indent-count: 2.0"><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">入门</SPAN></B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">：</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">JCL</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">有两个基本的抽象类：</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">Log(</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">基本纪录器</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">)</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">和</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">LogFactory</SPAN><SPAN lang=EN-US>(</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">负责创建</SPAN><SPAN lang=EN-US>Log</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实例</SPAN><SPAN lang=EN-US>)</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US>JCL</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">寻找日志工具的过程如下：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 63pt; TEXT-INDENT: -42pt; tab-stops: list 63.0pt; mso-list: l0 level1 lfo1"><SPAN lang=EN-US style="mso-bidi-font-family: 宋体"><SPAN style="mso-list: Ignore">一〉<SPAN style="FONT: 7pt 'Times New Roman'">              </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">寻找当前的</SPAN><SPAN lang=EN-US>factory</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中名叫</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">org.apache. commons.logging.Log</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">配置属性的值。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 63pt; TEXT-INDENT: -42pt; tab-stops: list 63.0pt; mso-list: l0 level1 lfo1"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 宋体"><SPAN style="mso-list: Ignore">二〉<SPAN style="FONT: 7pt 'Times New Roman'">              </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">寻找系统属性中名叫</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">org.apache.commons.logging.Log</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">的值。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 63pt; TEXT-INDENT: -42pt; tab-stops: list 63.0pt; mso-list: l0 level1 lfo1"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 宋体"><SPAN style="mso-list: Ignore">三〉<SPAN style="FONT: 7pt 'Times New Roman'">              </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">如果应用程序的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">CLASSPATH</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">中有</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">Log4j,</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">这是用相关的包装类（</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">wrapper</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">）类（</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">Log4Jlogger</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">）</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">.<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 63pt; TEXT-INDENT: -42pt; tab-stops: list 63.0pt; mso-list: l0 level1 lfo1"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 宋体"><SPAN style="mso-list: Ignore">四〉<SPAN style="FONT: 7pt 'Times New Roman'">              </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">如果应用程序运行在</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">jdk1.4</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">的系统中，使用相关的包装类</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">(JDK1.4logger).<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 63pt; TEXT-INDENT: -42pt; tab-stops: list 63.0pt; mso-list: l0 level1 lfo1"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 宋体"><SPAN style="mso-list: Ignore">五〉<SPAN style="FONT: 7pt 'Times New Roman'">              </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">使用简易日志包装类（</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">SimpleLog</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">）</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">.<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">使用</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">logging</SPAN></B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">:<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">import org.apache.commons.logging.Log;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">import org.apache.commons.logging.LogFactory;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">public class MyClass{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 36.75pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">private static Log log=LogFactory.getLog(this.CLASS);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 36.75pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">…………………………<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">这些日志信息被送往日志器，如上例中的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">Log</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">接口中的方法：</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 31.5pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">定义日志信息的级别，按严重性有：</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 31.5pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log.fatal(Object message);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 31.5pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log.fatal(Object message,Throwable t);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 31.5pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log.error(Object message);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 31.5pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log.error(Object message,Throwable t);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 31.5pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log.warn(Object message);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 31.5pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log.warn(Object message,Throwable t);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 31.5pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log.info(Object message);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 31.5pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log.info(Object message,Throwable t);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 31.5pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log.debug(Object message);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 31.5pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log.debug(Object message,Throwable t);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 31.5pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log.trace(Object message);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 31.5pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log.trace(Object message,Throwable t);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">fatal:</SPAN></B><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">非常严重的错误，导致系统终止。期望这类信息被立即显示到状态控制台上。</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">Error:</SPAN></B><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">其他运行期错误或不是预期的条件。期望这类信息被立即显示到状态控制台上。</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 31.6pt; TEXT-INDENT: -31.6pt; mso-char-indent-count: -3.0"><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">Warn:</SPAN></B><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">使用了不赞成使用的</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">API</SPAN></B><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">、非常拙劣的使用了</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">API</SPAN></B><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">、‘几乎就是错误’其他运行期不合需要和不合预期的状态（但没必要将其称为错误）。期望这类信息被立即显示到状态控制台上。</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">Info:</SPAN></B><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">运行期产生的有意义的事件。期望这类信息被立即显示到状态控制台上。</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">Debug:</SPAN></B><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">系统流程中的细节信息。期望这类信息仅被写入日志文件中。</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">Trace:</SPAN></B><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">更加细节的信息。期望这类信息仅被写入日志文件中。</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 36.75pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">用于代码保护</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">(</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">表示如果启用了某种日志信息级别</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">)</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">：</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 36.75pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log.isFatalEnabled();</SPAN></P><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 36.75pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log.isErrorEnabled();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 36.75pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log.isWarnEnabled();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 36.75pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log.isInfoEnabled();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 36.75pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log.isDebugEnabled();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 36.75pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log.isTraceEnabled();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">通常情况下，记录器的级别不低于</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">info,</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">通常情况下</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">debug</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">信息不应被写入</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">文件中。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">工作机理：</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 84pt; TEXT-INDENT: -42pt; tab-stops: list 84.0pt; mso-list: l0 level1 lfo1"><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 宋体"><SPAN style="mso-list: Ignore">一〉<SPAN style="FONT: 7pt 'Times New Roman'">             </SPAN></SPAN></SPAN></B><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">生命周期：</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">JCL LogFactory</SPAN></B><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">必须实现建立</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">/</SPAN></B><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">断开到日志工具的连接，实例化</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">/</SPAN></B><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">初始化</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">/</SPAN></B><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">解构一个日志工具。</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 84pt; TEXT-INDENT: -42pt; tab-stops: list 84.0pt; mso-list: l0 level1 lfo1"><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 宋体"><SPAN style="mso-list: Ignore">二〉<SPAN style="FONT: 7pt 'Times New Roman'">             </SPAN></SPAN></SPAN></B><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">异常处理：</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">JCL Log</SPAN></B><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">接口没有实现任何异常处理，对接口的实现必须捕获并处理异常。</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">记录器的设置：</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">log4j</SPAN></B><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">时</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">JCL</SPAN></B><B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">的首选记录器：</SPAN></B><B><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 36.75pt">
<TABLE class=MsoNormalTable style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-table-layout-alt: fixed; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellSpacing=0 cellPadding=0 border=1>
<TBODY>
<TR>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 130.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt" width=174>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">参数</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 90.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt" width=121>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">值域</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 135pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt" width=180>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">默认值</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 69.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt" width=93>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">说明</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></P></TD></TR>
<TR>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 130.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" width=174>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">Log4j.configuration<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 90.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" width=121>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p> </o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 135pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" width=180>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">Log4j.properties<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 69.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" width=93>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">指定配置文件的名字</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></P></TD></TR>
<TR>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 130.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" width=174>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">Log4j.rootCategory<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 90.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" width=121>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">Priority[,appender].*<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 135pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" width=180>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p> </o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 69.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" width=93>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">设定根记录器级别</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></P></TD></TR>
<TR>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 130.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" width=174>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">Log4j.logger.<logger.name><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 90.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" width=121>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">Debug,info,trace,error,fatal<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 135pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" width=180>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">设定</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><logger.name></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">这个记录器的级别</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 69.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" width=93>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p> </o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-lastrow: yes">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 130.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" width=174>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">Log4j.appender.<appender>.Threshold<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 90.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" width=121>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">priority<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 135pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" width=180>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">指定纪录设备</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><appender></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">的最低级别（</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'">console,files,sockets,others</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New'">）</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 69.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" width=93>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Courier New'"><o:p> </o:p></SPAN></P></TD></TR></TBODY></TABLE></o:p></SPAN></P><img src ="http://www.blogjava.net/chhbjh/aggbug/12305.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chhbjh/" target="_blank">阳光咖啡</a> 2005-09-07 11:33 <a href="http://www.blogjava.net/chhbjh/archive/2005/09/07/12305.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>