﻿<?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-study-随笔分类-JAVA语言</title><link>http://www.blogjava.net/xixidabao/category/15384.html</link><description>GROW WITH JAVA</description><language>zh-cn</language><lastBuildDate>Sun, 27 Jan 2008 03:09:44 GMT</lastBuildDate><pubDate>Sun, 27 Jan 2008 03:09:44 GMT</pubDate><ttl>60</ttl><item><title>MessageDigest对密码进行加密</title><link>http://www.blogjava.net/xixidabao/archive/2008/01/26/177892.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Sat, 26 Jan 2008 04:16:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2008/01/26/177892.html</guid><description><![CDATA[时候，我们必须把用户密码存放到数据库，为了安全起见，我们需要对这些密码进行单向的加密处理，<br />
比如，有明文密码如下：<br />
String originalPwd = "mypassword";
<p>应用报文摘要方法，得到单向的加密字符串 </p>
<p>//MD5是16位,SHA是20位（这是两种报文摘要的算法）<br />
//MessageDigest md= MessageDigest.getInstance("MD5");<br />
MessageDigest messageDigest=MessageDigest.getInstance("SHA-1");<br />
messageDigest.update(originalPwd.getBytes());<br />
//String digestedPwdString = new String(messageDigest.digest());<br />
String digestedPwdString = new String(Base64.encode(messageDigest.digest()));<br />
System.out.println("pwd:" + digestedPwdString);<br />
这样，就得到密码的报文摘要，把此摘要保存到数据库，<br />
以后用户登陆时，用相同的算法算出摘要，和数据库中的比较，如果一致，则密码正确。 </p>
<p>注意：<br />
byte[] digest = messageDigest.digest();<br />
得到的是个二进制byte数组，有可能某些byte是不可打印的字符。<br />
所以用Base64.encode把它转化成可打印字符。 </p>
<p>也可以把digest的每个byte转化成hex（16进制）保存。<br />
MessageDigest messageDigest=MessageDigest.getInstance("SHA-1");<br />
messageDigest.update(originalPwd.getBytes());<br />
byte[] bin = messageDigest.digest()；<br />
再调用下面的方法生产hex（16进制）保存。 </p>
<p><br />
二行制转hex字符串的方法如下：<br />
private static String byte2hex(byte[] b){<br />
&nbsp;&nbsp;&nbsp; String hs="";<br />
&nbsp;&nbsp;&nbsp; String stmp="";<br />
&nbsp;&nbsp;&nbsp; for (int n=0; n&lt;b.length; n++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stmp=(java.lang.Integer.toHexString(b[n] &amp; 0xFF));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (stmp.length()==1) hs=hs+"0"+stmp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else hs=hs+stmp;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; return hs;<br />
} </p>
<p>或者：<br />
private static String byto2hex2(byte[] bin){<br />
&nbsp;&nbsp;&nbsp; StringBuffer buf = new StringBuffer();<br />
&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; bin.length; ++i) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int x = bin[i] &amp; 0xFF, h = x &gt;&gt;&gt; 4, l = x &amp; 0x0F;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf.append((char) (h + ((h &lt; 10) ? '0' : 'a' - 10)));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf.append((char) (l + ((l &lt; 10) ? '0' : 'a' - 10)));<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; return buf.toString();<br />
} </p>
<p>或者:<br />
干脆直接用下面的方法生成，用到第三方包：<br />
public static String encryptPwd(String pwd, String algorithm){<br />
&nbsp;&nbsp;&nbsp; //String a = org.apache.catalina.realm.RealmBase.Digest(pwd,"SHA-1");<br />
&nbsp;&nbsp;&nbsp; return org.apache.catalina.realm.RealmBase.Digest(pwd, algorithm);<br />
}</p>
&nbsp; <br />
<br />
http://www.ibm.com/developerworks/cn/java/l-security/index.html
<img src ="http://www.blogjava.net/xixidabao/aggbug/177892.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2008-01-26 12:16 <a href="http://www.blogjava.net/xixidabao/archive/2008/01/26/177892.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java NIO API详解</title><link>http://www.blogjava.net/xixidabao/archive/2008/01/18/176208.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Fri, 18 Jan 2008 06:47:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2008/01/18/176208.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Java NIO API详解&nbsp;&nbsp;&nbsp;&nbsp; 选择自 DaiJiaLin 的 Blog &nbsp;在JDK 1.4以前，Java的IO操作集中在java.io这个包中，是基于流的同步（blocking）API。对于大多数应用来说，这样的API使用很方便，然而，一些对性能要求较高的应用，尤其是服务端应用，往往需要一个更为有效的方式来处理IO。从JDK 1.4...&nbsp;&nbsp;<a href='http://www.blogjava.net/xixidabao/archive/2008/01/18/176208.html'>阅读全文</a><img src ="http://www.blogjava.net/xixidabao/aggbug/176208.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2008-01-18 14:47 <a href="http://www.blogjava.net/xixidabao/archive/2008/01/18/176208.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>写得蛮好的linux学习笔记</title><link>http://www.blogjava.net/xixidabao/archive/2007/08/14/136537.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Mon, 13 Aug 2007 16:21:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2007/08/14/136537.html</guid><description><![CDATA[<div>
<div>
<div>linux<font face=宋体>目录架构</font><br>/ &nbsp; <font face=宋体>根目录</font><br>/bin&nbsp;&nbsp;&nbsp; <font face=宋体>常用的命令</font> binary file <font face=宋体>的目錄</font><br>/boot&nbsp;&nbsp; <font face=宋体>存放系统启动时必须读取的档案，包括核心</font> (kernel) <font face=宋体>在内</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /boot/grub/menu.lst&nbsp;&nbsp; GRUB<font face=宋体>设置</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /boot/vmlinuz&nbsp;&nbsp; <font face=宋体>内核</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /boot/initrd&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>核心解壓縮所需</font> RAM Disk<br>/dev&nbsp;&nbsp;&nbsp; <font face=宋体>系统周边设备</font>&nbsp;&nbsp;&nbsp;&nbsp; <br>/etc&nbsp;&nbsp;&nbsp; <font face=宋体>系统相关设定文件</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/DIR_COLORS&nbsp;&nbsp; <font face=宋体>设定颜色</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/HOSTNAME&nbsp;&nbsp; <font face=宋体>设定用户的节点名</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/NETWORKING&nbsp;&nbsp; <font face=宋体>只有</font>YES<font face=宋体>标明网络存在</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/host.conf <font face=宋体>文件说明用户的系统如何查询节点名</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/hosts <font face=宋体>设定用户自已的</font>IP<font face=宋体>与名字的对应表</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/hosts.allow <font face=宋体>设置允许使用</font>inetd<font face=宋体>的机器使用</font> <br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/hosts.deny <font face=宋体>设置不允许使用</font>inetd<font face=宋体>的机器使用</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/hosts.equiv <font face=宋体>设置远端机不用密码</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/inetd.conf <font face=宋体>设定系统网络守护进程</font>inetd<font face=宋体>的配置</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/gateways <font face=宋体>设定路由器</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/protocols <font face=宋体>设定系统支持的协议</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/named.boot <font face=宋体>设定本机为名字服务器的配置文件</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/sysconfig/network-scripts/ifcfg-eth0&nbsp;&nbsp; <font face=宋体>设置</font>IP<br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/resolv.conf&nbsp;&nbsp;&nbsp; <font face=宋体>设置</font>DNS&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/X11&nbsp; X Window<font face=宋体>的配置文件</font>,xorg.conf <font face=宋体>或</font> XF86Config <font face=宋体>這兩個</font> X Server <font face=宋体>的設定檔</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/fstab&nbsp;&nbsp;&nbsp; <font face=宋体>记录开机要</font>mount<font face=宋体>的文件系统</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/inittab <font face=宋体>设定系统启动时</font>init<font face=宋体>进程将把系统设置成什么样的</font>runlevel<br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/issue <font face=宋体>记录用户登录前显示的信息</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/group <font face=宋体>设定用户的组名与相关信息</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/passwd <font face=宋体>帐号信息</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/shadow <font face=宋体>密码信息</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/sudoers <font face=宋体>可以</font>sudo<font face=宋体>命令的配置文件</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/securetty <font face=宋体>设定哪些终端可以让</font>root<font face=宋体>登录</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/login.defs <font face=宋体>所有用户登录时的缺省配置</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/exports <font face=宋体>设定</font>NFS<font face=宋体>系统用的</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/init.d/&nbsp;&nbsp; <font face=宋体>所有服務的預設啟動</font> script <font face=宋体>都是放在這裡的，例如要啟動或者關閉</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/xinetd.d/&nbsp; <font face=宋体>這就是所謂的</font> super daemon <font face=宋体>管理的各項服務的設定檔目錄</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/modprobe.conf&nbsp;&nbsp; <font face=宋体>内核模块额外参数设定</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/syslog.conf&nbsp;&nbsp; <font face=宋体>日志设置文件</font><br>/home&nbsp;&nbsp; <font face=宋体>使用者家目录</font><br>/lib&nbsp;&nbsp;&nbsp; <font face=宋体>系统会使用到的函数库</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /lib/modules&nbsp;&nbsp; kernel <font face=宋体>的相关模块</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /var/lib/rpm&nbsp;&nbsp; rpm<font face=宋体>套件安装处</font> <br>/lost+found&nbsp;&nbsp;&nbsp; <font face=宋体>系統不正常產生錯誤時，會將一些遺失的片段放置於此目錄下</font><br>/mnt&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>外设的挂载点</font><br>/media&nbsp;&nbsp; <font face=宋体>与</font>/mnt<font face=宋体>类似</font><br>/opt&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>主机额外安装的软件</font><br>/proc&nbsp;&nbsp;&nbsp; <font face=宋体>虚拟目录，是内存的映射</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /proc/version&nbsp;&nbsp; <font face=宋体>内核版本</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /proc/sys/kernel&nbsp;&nbsp; <font face=宋体>系统内核功能</font><br>/root&nbsp;&nbsp;&nbsp; <font face=宋体>系统管理员的家目录</font><br>/sbin&nbsp;&nbsp;&nbsp; <font face=宋体>系统管理员才能执行的指令</font><br>/srv&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>一些服務啟動之後，這些服務所需要取用的資料目錄</font><br>/tmp&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>一般使用者或者是正在執行的程序暫時放置檔案的地方</font><br>/usr&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>最大的目录，存许应用程序和文件</font><br>&nbsp;&nbsp;&nbsp; /usr/X11R6<font face=宋体>：</font>&nbsp;&nbsp; X-Window<font face=宋体>目录</font> <br>&nbsp;&nbsp;&nbsp; /usr/src<font face=宋体>：</font>&nbsp;&nbsp;&nbsp; Linux<font face=宋体>源代码</font><br>&nbsp;&nbsp;&nbsp; /usr/include<font face=宋体>：系统头文件</font><br>&nbsp;&nbsp;&nbsp; /usr/openwin <font face=宋体>存放</font>SUN<font face=宋体>的</font>OpenWin <br>&nbsp;&nbsp;&nbsp; /usr/man <font face=宋体>在线使用手册</font><br>&nbsp;&nbsp;&nbsp; /usr/bin&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>使用者可執行的</font> binary file <font face=宋体>的目錄</font><br>&nbsp;&nbsp;&nbsp; /usr/local/bin&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>使用者可執行的</font> binary file <font face=宋体>的目錄</font><br>&nbsp;&nbsp;&nbsp; /usr/lib&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>系统会使用到的函数库</font><br>&nbsp;&nbsp;&nbsp; /usr/local/lib&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>系统会使用到的函数库</font><br>&nbsp;&nbsp;&nbsp; /usr/sbin&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>系统管理员才能执行的指令</font><br>&nbsp;&nbsp;&nbsp; /usr/local/sbin&nbsp;&nbsp;&nbsp; <font face=宋体>系统管理员才能执行的指令</font><br>/var&nbsp;&nbsp; <font face=宋体>日志文件</font><br>&nbsp;&nbsp;&nbsp; /var/log/secure&nbsp;&nbsp;&nbsp; <font face=宋体>記錄登入系統存取資料的檔案，例如</font> pop3, ssh, telnet, ftp <font face=宋体>等都會記錄在此檔案中</font><br>&nbsp;&nbsp;&nbsp; /var/log/wtmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>記錄登入者的訊息資料</font>, last<br>&nbsp;&nbsp;&nbsp; /var/log/messages&nbsp; <font face=宋体>幾乎系統發生的錯誤訊息</font><br>&nbsp;&nbsp;&nbsp; /var/log/boot.log&nbsp; <font face=宋体>記錄開機或者是一些服務啟動的時候，所顯示的啟動或關閉訊息</font><br>&nbsp;&nbsp;&nbsp; /var/log/maillog&nbsp;&nbsp; <font face=宋体>紀錄郵件存取或往來</font>( sendmail <font face=宋体>與</font> pop3 )<font face=宋体>的使用者記錄</font><br>&nbsp;&nbsp;&nbsp; /var/log/cron&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>記錄</font> crontab <font face=宋体>這個例行性服務的內容</font><br>&nbsp;&nbsp;&nbsp; /var/log/httpd, /var/log/news, /var/log/mysqld.log, /var/log/samba, /var/log/procmail.log<font face=宋体>：</font><br>&nbsp;&nbsp;&nbsp; <font face=宋体>分別是幾個不同的網路服務的記錄檔</font></div>
<div>&nbsp;</div>
<div><font face=宋体>一些常用的基本命令</font>:<br>uname -a&nbsp;&nbsp;&nbsp; <font face=宋体>查看内核版本</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>ls -al&nbsp;&nbsp;&nbsp; <font face=宋体>显示所有文件的属性</font><br>pwd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示当前路径</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>cd -&nbsp;&nbsp;&nbsp; <font face=宋体>返回上一次目录</font>&nbsp;&nbsp;&nbsp;&nbsp; cd ~&nbsp;&nbsp;&nbsp; <font face=宋体>返回主目录</font><br>date s&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>设置时间、日期</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>cal&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示日历</font>&nbsp;&nbsp;&nbsp;&nbsp; cal 2006<br>bc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>计算器具</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>man&nbsp; &amp; info&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>帮助手册</font><br>locale&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示当前字体</font>&nbsp;&nbsp;&nbsp;&nbsp; locale -a&nbsp;&nbsp;&nbsp; <font face=宋体>所有可用字体</font>&nbsp;&nbsp;&nbsp;&nbsp; /etc/sysconfig/i18n<font face=宋体>设置文件</font><br>LANG=en&nbsp;&nbsp;&nbsp; <font face=宋体>使用英文字体</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>sync&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>将数据同步写入硬盘</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>shutdonw -h now &amp; half &amp; poweroff&nbsp; <font face=宋体>关机</font><br>reboot&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>重启</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>startx&nbsp; &amp;&nbsp; init 5&nbsp;&nbsp; <font face=宋体>进入图形介面</font><br>/work&nbsp; &amp; ?work&nbsp;&nbsp;&nbsp; <font face=宋体>向上、下查找文档内容</font><br>chgrp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>改变档案群组</font>&nbsp; chgrp testing install.log&nbsp;&nbsp;&nbsp; <br>chown&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>改变所属人</font>&nbsp;&nbsp; chown root:root install.log<br>chmod&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>改变属性</font>&nbsp;&nbsp;&nbsp;&nbsp; chmod 777 install.log&nbsp;&nbsp;&nbsp;&nbsp; read=4&nbsp; write=2&nbsp; execute=1<br>cp&nbsp;&nbsp; <font face=宋体>复制</font>&nbsp;&nbsp; cp filename<br>rm&nbsp;&nbsp; <font face=宋体>删除文件</font>&nbsp; rm -rf filename&nbsp;&nbsp; <font face=宋体>强制删除文件</font><br>rmdir&nbsp;&nbsp; <font face=宋体>删除文件夹</font><br>mv&nbsp; <font face=宋体>移动</font>&nbsp;&nbsp;&nbsp; mv 123.txt 222.txt&nbsp; <font face=宋体>重命名</font><br>mkdir&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>创建文件夹</font><br>touch&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>创建文件</font>&nbsp; <font face=宋体>更新当前时间</font><br>cat&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>由第一行开始显示</font>&nbsp;&nbsp;&nbsp;&nbsp; cat |more&nbsp; <font face=宋体>分页</font><br>nl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>在内容前加行号</font><br>more&nbsp; &amp;&nbsp; less&nbsp;&nbsp; <font face=宋体>一面一面翻动</font><br>head -n filename&nbsp;&nbsp; <font face=宋体>显示第</font>N<font face=宋体>行内容</font><br>tail -n filename&nbsp; <font face=宋体>显示后</font>N<font face=宋体>行内容</font><br>od&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示非纯文档</font><br>df -h <font face=宋体>显示分区空间</font><br>du&nbsp; <font face=宋体>显示目录或文件的大小</font><br>fdisk&nbsp;&nbsp; <font face=宋体>分区设置</font>&nbsp;&nbsp;&nbsp; fdisk -l /dev/hda&nbsp; <font face=宋体>显示硬盘分区状态</font><br>mkfs&nbsp;&nbsp;&nbsp; <font face=宋体>建立各种文件系统</font>&nbsp; mkfs -t ext3&nbsp; /dev/ram15&nbsp;&nbsp; <br>fsck&nbsp;&nbsp;&nbsp; <font face=宋体>检查和修复</font>LINUX<font face=宋体>档案</font><br>ln&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>硬链接</font>&nbsp;&nbsp; ln -s&nbsp; <font face=宋体>软件链接</font><br>whereis&nbsp;&nbsp; <font face=宋体>查找命令</font><br>locate&nbsp;&nbsp;&nbsp; <font face=宋体>查找</font><br>find&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>查找</font>&nbsp;&nbsp; find / -name "***.***"<br>which&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>查看工具</font><br>whoami&nbsp;&nbsp;&nbsp; <font face=宋体>显示当前用户</font><br>gcc -v&nbsp;&nbsp;&nbsp; <font face=宋体>查看</font>GCC<font face=宋体>版本</font><br>chattr +i filename&nbsp; <font face=宋体>禁止删除</font>&nbsp;&nbsp; chattr -i filename&nbsp; <font face=宋体>取消禁止</font><br>lsattr&nbsp;&nbsp;&nbsp; <font face=宋体>显示隐藏档属性</font><br>updatedb&nbsp; <font face=宋体>更新资料库</font><br>mke2fs&nbsp;&nbsp;&nbsp; <font face=宋体>格式化</font>&nbsp;&nbsp; mkfs -t ext3 <br>dd if=/etc/passwd of=/tmp/passwd.bak&nbsp;&nbsp;&nbsp; <font face=宋体>备份</font><br>mount&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>列出系统所有的分区</font><br>mount -t iso9660 /dev/cdrom /mnt/cdrom&nbsp;&nbsp; <font face=宋体>挂载光盘</font><br>mount -t vfat /dev/fd0 /mnt/floppy&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>挂载软盘</font><br>mount -t vfat -o iocharset=utf8,umask=000 /dev/hda2 /mnt/hda2&nbsp;&nbsp; <font face=宋体>挂载</font>fat32<font face=宋体>分区</font><br>mount -t ntfs -o nls=utf8,umask=000 /dev/hda3 /mnt/hda3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>挂载</font>ntfs<font face=宋体>分区</font><br>Linux-NTFS Project: <a href="http://linux-ntfs.sourceforge.net/"><font color=#223355><u>http://linux-ntfs.sourceforge.net/</u></font></a><br>umount /mnt/hda3&nbsp; <font face=宋体>缷载</font><br>ifconfig&nbsp;&nbsp; <font face=宋体>显示或设置网络设备</font><br>service network restart&nbsp;&nbsp; <font face=宋体>重启网卡</font>&nbsp; <br>ifdown eth0&nbsp; <font face=宋体>关闭网卡</font><br>ifup eth0&nbsp;&nbsp;&nbsp; <font face=宋体>开启网卡</font><br>clear&nbsp;&nbsp;&nbsp; <font face=宋体>清屏</font><br>history&nbsp;&nbsp;&nbsp; <font face=宋体>历史记录</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !55&nbsp; <font face=宋体>执行第</font>55<font face=宋体>个指令</font><br>stty&nbsp;&nbsp; <font face=宋体>设置终端</font>&nbsp;&nbsp;&nbsp; stty -a<br>fdisk /mbr&nbsp;&nbsp; <font face=宋体>删除</font>GRUB<br>at&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>僅進行一次的工作排程</font><br>crontab&nbsp;&nbsp; <font face=宋体>循環執行的例行性命令</font>&nbsp;&nbsp;&nbsp; [e]<font face=宋体>编辑</font>,[l]<font face=宋体>显示</font>,[r]<font face=宋体>删除任务</font><br>&amp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>后台运行程序</font>&nbsp;&nbsp;&nbsp; tar -zxvf 123.tar.gz &amp; ---------&gt;<font face=宋体>后台运行</font><br>jobs&nbsp;&nbsp;&nbsp; <font face=宋体>观看后台暂停的程序</font>&nbsp;&nbsp; jobs -l<br>fg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>将后台程序调到前台</font>&nbsp;&nbsp; fg n ------&gt;n<font face=宋体>是数字</font>,<font face=宋体>可以指定进行那个程序</font><br>bg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>让工作在后台运行</font><br>kill&nbsp;&nbsp;&nbsp; <font face=宋体>结束进程</font>&nbsp;&nbsp;&nbsp; kill -9 PID&nbsp;&nbsp;&nbsp;&nbsp; [9]<font face=宋体>强制结束</font>,[15]<font face=宋体>正常结束</font>,[l]<font face=宋体>列出可用的</font>kill<font face=宋体>信号</font><br>ps aux&nbsp; <font face=宋体>查看后台程序</font>&nbsp;&nbsp; <br>top&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>查看后台程序</font>&nbsp;&nbsp; top -d 2&nbsp;&nbsp;&nbsp; <font face=宋体>每两秒更新一次</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; top -d 2 -p10604&nbsp;&nbsp; <font face=宋体>观看某个</font>PID<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; top -b -n 2 &gt; /tmp/top.txt -----&gt;<font face=宋体>將</font> top <font face=宋体>的資訊進行</font> 2 <font face=宋体>次，然後將結果輸出到</font> /tmp/top.txt&nbsp;&nbsp;&nbsp; <br>pstree&nbsp;&nbsp; <font face=宋体>以树状图显示程序</font>&nbsp;&nbsp;&nbsp; [A]<font face=宋体>以</font> ASCII <font face=宋体>來連接</font>, [u]<font face=宋体>列出</font>PID, [p]<font face=宋体>列出帐号</font><br>killall&nbsp;&nbsp; <font face=宋体>要刪除某個服務</font>&nbsp;&nbsp;&nbsp; killall -9 httpd<br>free&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示内存状态</font>&nbsp;&nbsp;&nbsp;&nbsp; free -m&nbsp; --------&gt;<font face=宋体>以</font>M<font face=宋体>为单位显示</font><br>uptime&nbsp;&nbsp;&nbsp; <font face=宋体>显示目前系统开机时间</font><br>netstat&nbsp;&nbsp; <font face=宋体>显示网络状态</font>&nbsp;&nbsp;&nbsp; netstat -tulnp------&gt;<font face=宋体>找出目前系統上已在監聽的網路連線及其</font> PID<br>dmesg&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示开机信息</font>&nbsp;&nbsp;&nbsp; demsg | more<br>nice&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>设置优先权</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nice -n -5 vi &amp; -----&gt;<font face=宋体>用</font> root <font face=宋体>給一個</font> nice <font face=宋体>植為</font> -5 <font face=宋体>，用於執行</font> vi <br>renice&nbsp;&nbsp;&nbsp; <font face=宋体>调整已存在优先权</font><br>runlevel&nbsp; <font face=宋体>显示目前的</font>runlevel<br>depmod&nbsp;&nbsp;&nbsp; <font face=宋体>分析可载入模块的相依性</font><br>lsmod&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示已载入系统的模块</font><br>modinfo&nbsp;&nbsp; <font face=宋体>显示</font>kernel<font face=宋体>模块的信息</font><br>insmod&nbsp;&nbsp;&nbsp; <font face=宋体>载入模块</font><br>modprobe&nbsp;&nbsp; <font face=宋体>自动处理可载入模块</font><br>rmmod&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>删除模块</font><br>chkconfig&nbsp;&nbsp; <font face=宋体>检查，设置系统的各种服务</font>&nbsp;&nbsp;&nbsp;&nbsp; chkconfig --list -----&gt;<font face=宋体>列出各项服务状态</font><br>ntsysv&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>设置系统的各种服务</font><br>cpio&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>备份文件</font><br>&nbsp;</div>
<div><br><font face=宋体>压缩命令：</font><br>&nbsp;*.Z&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; compress <font face=宋体>程式壓縮的檔案；</font> <br>&nbsp;*.bz2&nbsp;&nbsp;&nbsp; bzip2 <font face=宋体>程式壓縮的檔案；</font> <br>&nbsp;*.gz&nbsp;&nbsp;&nbsp;&nbsp; gzip <font face=宋体>程式壓縮的檔案；</font> <br>&nbsp;*.tar&nbsp;&nbsp;&nbsp; tar <font face=宋体>程式打包的資料，並沒有壓縮過；</font> <br>&nbsp;*.tar.gz tar <font face=宋体>程式打包的檔案，其中並且經過</font> gzip <font face=宋体>的壓縮</font><br>compress filename&nbsp; <font face=宋体>压缩文件</font>&nbsp; <font face=宋体>加</font>[-d]<font face=宋体>解压</font>&nbsp; uncompress<br>gzip filename&nbsp;&nbsp; <font face=宋体>压缩</font>&nbsp; <font face=宋体>加</font>[-d]<font face=宋体>解压</font>&nbsp; zcat 123.gz <font face=宋体>查看压缩文件内容</font><br>bzip2 -z filename&nbsp; <font face=宋体>压缩</font>&nbsp; <font face=宋体>加</font>[-d]<font face=宋体>解压</font>&nbsp;&nbsp; bzcat filename.bz2&nbsp; <font face=宋体>查看压缩文件内容</font><br>tar -cvf /home/123.tar /etc&nbsp; <font face=宋体>打包，不压缩</font><br>tar -xvf 123.tar&nbsp;&nbsp; <font face=宋体>解开包</font><br>tar -zxvf /home/123.tar.gz&nbsp; <font face=宋体>以</font>gzip<font face=宋体>解压</font><br>tar -jxvf /home/123.tar.bz2&nbsp; <font face=宋体>以</font>bzip2<font face=宋体>解压</font><br>tar -ztvf /tmp/etc.tar.gz&nbsp;&nbsp; <font face=宋体>查看</font>tar<font face=宋体>内容</font><br>cpio -covB&nbsp; &gt; [file|device]&nbsp;&nbsp; <font face=宋体>份份</font><br>cpio -icduv &lt; [file|device]&nbsp;&nbsp; <font face=宋体>还原</font></div>
<div>&nbsp;</div>
<div>vi<font face=宋体>一般用法</font><br><font face=宋体>一般模式</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>编辑模式</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>指令模式</font><br>h <font face=宋体>左</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a,i,r,o,A,I,R,O&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :w <font face=宋体>保存</font><br>j <font face=宋体>下</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>进入编辑模式</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :w! <font face=宋体>强制保存</font><br>k <font face=宋体>上</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dd <font face=宋体>删除光标当前行</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :q! <font face=宋体>不保存离开</font><br>l <font face=宋体>右</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ndd <font face=宋体>删除</font>n<font face=宋体>行</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :wq! <font face=宋体>保存后离开</font><br>0 <font face=宋体>移动到行首</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; yy <font face=宋体>复制当前行</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :e! <font face=宋体>还原原始档</font><br>$ <font face=宋体>移动到行尾</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nyy <font face=宋体>复制</font>n<font face=宋体>行</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :w filename <font face=宋体>另存为</font><br>H <font face=宋体>屏幕最上</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p,P <font face=宋体>粘贴</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :set nu <font face=宋体>设置行号</font><br>M <font face=宋体>屏幕中央</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u&nbsp; <font face=宋体>撤消</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :set nonu <font face=宋体>取消行号</font><br>L <font face=宋体>屏幕最下</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Ctrl]+r <font face=宋体>重做上一个动作</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ZZ <font face=宋体>保存离开</font><br>G <font face=宋体>档案最后一行</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ctrl]+z <font face=宋体>暂停退出</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :set nohlsearch&nbsp;&nbsp; <font face=宋体>永久地关闭高亮显示</font><br>/work <font face=宋体>向下搜索</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :sp <font face=宋体>同时打开两个文档</font> <br>?work <font face=宋体>向上搜索</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Ctrl]+w <font face=宋体>两个文档设换</font><br>gg <font face=宋体>移动到档案第一行</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :nohlsearch&nbsp;&nbsp;&nbsp; <font face=宋体>暂时关闭高亮显示</font></div>
<div>&nbsp;</div>
<div><font face=宋体>认识</font>SHELL<br>alias&nbsp;&nbsp;&nbsp; <font face=宋体>显示当前所有的命令别名</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alias lm="ls -al"&nbsp;&nbsp; <font face=宋体>命令别名</font>&nbsp;&nbsp;&nbsp; unalias lm <font face=宋体>取消命令别名</font><br>type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>类似</font>which<br>exprot&nbsp;&nbsp;&nbsp; <font face=宋体>设置或显示环境变量</font><br>exprot PATH="$PATH":/sbin&nbsp; <font face=宋体>添加</font>/sbin<font face=宋体>入</font>PATH<font face=宋体>路径</font><br>echo $PATH&nbsp;&nbsp;&nbsp; <font face=宋体>显示</font>PATH<font face=宋体>路径</font><br>bash&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>进入子程序</font><br>name=yang&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>设定变量</font><br>unset name&nbsp;&nbsp;&nbsp; <font face=宋体>取消变量</font><br>echo $name&nbsp;&nbsp;&nbsp; <font face=宋体>显示变量的内容</font><br>myname="$name its me"&nbsp;&nbsp; &amp;&nbsp;&nbsp; myname='$name its me'&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>单引号时</font>$name<font face=宋体>失去变量内容</font><br>ciw=/etc/sysconfig/network-scripts/&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>设置路径</font><br>env&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>列出所有环境变量</font><br>echo $RANDOM&nbsp;&nbsp;&nbsp; <font face=宋体>显示随意产生的数</font><br>set&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>设置</font>SHELL<br>PS1='[\u@\h \w \A #\#]\$ '&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>提示字元的設定</font><br>&nbsp;&nbsp; [root@linux ~]# read [-pt] variable&nbsp;&nbsp;&nbsp;&nbsp; -----------<font face=宋体>读取键盘输入的变量</font><br>&nbsp;&nbsp; <font face=宋体>參數：</font><br>&nbsp;&nbsp; -p&nbsp; <font face=宋体>：後面可以接提示字元！</font><br>&nbsp;&nbsp; -t&nbsp; <font face=宋体>：後面可以接等待的『秒數！』</font><br>declare&nbsp;&nbsp;&nbsp; <font face=宋体>声明</font> shell <font face=宋体>变量</font><br>ulimit -a&nbsp;&nbsp; <font face=宋体>显示所有限制资料</font><br>&nbsp;ls /tmp/yang &amp;&amp; echo "exist" || echo "not exist"<br>&nbsp;<font face=宋体>意思是說，當</font> ls /tmp/yang <font face=宋体>執行後，若正確，就執行</font>echo "exist" ,<font face=宋体>若有問題，就執行</font>echo "not exist" <br>&nbsp;echo $PATH | cut -d ':' -f 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>以</font>:<font face=宋体>为分隔符</font>,<font face=宋体>读取第</font>5<font face=宋体>段内容</font><br>&nbsp;export | cut -c 10-20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>读取第</font>10<font face=宋体>到</font>20<font face=宋体>个字节的内容</font><br>&nbsp;last | grep 'root'&nbsp;&nbsp;&nbsp; <font face=宋体>搜索有</font>root<font face=宋体>的一行</font>,<font face=宋体>加</font>[-v]<font face=宋体>反向搜索</font><br>&nbsp;cat /etc/passwd | sort&nbsp;&nbsp;&nbsp; <font face=宋体>排序显示</font><br>&nbsp;cat /etc/passwd | wc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示『行、字数、字节数』</font></div>
<div><font face=宋体>正规表示法</font><br>[root@test root]# grep [-acinv] '<font face=宋体>搜尋字串</font>' filename<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>參數說明：</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -a <font face=宋体>：將</font> binary <font face=宋体>檔案以</font> text <font face=宋体>檔案的方式搜尋資料</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -c <font face=宋体>：計算找到</font> '<font face=宋体>搜尋字串</font>' <font face=宋体>的次數</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -i <font face=宋体>：忽略大小寫的不同，所以大小寫視為相同</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -n <font face=宋体>：順便輸出行號</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -v <font face=宋体>：反向選擇，亦即顯示出沒有</font> '<font face=宋体>搜尋字串</font>' <font face=宋体>內容的那一行！</font><br>&nbsp;grep -n 'the' 123.txt&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>搜索</font>the<font face=宋体>字符</font> -----------<font face=宋体>搜尋特定字串</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;grep -n 't[ea]st' 123.txt&nbsp;&nbsp;&nbsp; <font face=宋体>搜索</font>test<font face=宋体>或</font>taste<font face=宋体>两个字符</font>---------<font face=宋体>利用</font> [] <font face=宋体>來搜尋集合字元</font><br>&nbsp;grep -n '[^g]oo' 123.txt&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>搜索前面不为</font>g<font face=宋体>的</font>oo-----------<font face=宋体>向選擇</font> [^] <br>&nbsp;grep -n '[0-9]' 123.txt&nbsp; <font face=宋体>搜索有</font>0-9<font face=宋体>的数字</font><br>&nbsp;grep -n '^the' 123.txt <font face=宋体>搜索以</font>the<font face=宋体>为行首</font>-----------<font face=宋体>行首搜索</font>^<br>&nbsp;grep -n '^[^a-zA-Z]' 123.txt&nbsp; <font face=宋体>搜索不以英文字母开头</font><br>&nbsp;grep -n '[a-z]$' 123.txt&nbsp;&nbsp;&nbsp; <font face=宋体>搜索以</font>a-z<font face=宋体>结尾的行</font>---------- <font face=宋体>行尾搜索</font>$<br>&nbsp;grep -n 'g..d' 123.txt&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>搜索开头</font>g<font face=宋体>结尾</font>d<font face=宋体>字符</font>----------<font face=宋体>任意一個字元</font> . <br>&nbsp;grep -n 'ooo*' 123.txt&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>搜索至少有两个</font>oo<font face=宋体>的字符</font>---------<font face=宋体>重複字元</font> *<br>sed&nbsp;&nbsp;&nbsp; <font face=宋体>文本流编辑器</font>&nbsp;&nbsp;&nbsp; <font face=宋体>利用脚本命令来处理文本文件</font><br>awd&nbsp;&nbsp;&nbsp; <font face=宋体>模式扫描和处理语言</font><br>&nbsp;nl 123.txt | sed '2,5d'&nbsp;&nbsp; <font face=宋体>删除第二到第五行的内容</font><br>diff&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>比较文件的差异</font><br>cmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>比较两个文件是否有差异</font><br>patch&nbsp;&nbsp;&nbsp; <font face=宋体>修补文件</font><br>pr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>要打印的文件格式化</font><br>&nbsp;</div>
<div><br><font face=宋体>帐号管理</font><br>/etc/passwd&nbsp;&nbsp;&nbsp; <font face=宋体>系统帐号信息</font><br>/etc/shadow&nbsp;&nbsp;&nbsp; <font face=宋体>帐号密码信息</font>&nbsp;&nbsp;&nbsp; <font face=宋体>经</font>MD5 32<font face=宋体>位加密</font><br>&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>在密码栏前面加『</font> * <font face=宋体>』『</font> ! <font face=宋体>』禁止使用某帐号</font><br>/etc/group&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>系统群组信息</font><br>/etc/gshadow<br>newgrp&nbsp;&nbsp;&nbsp; <font face=宋体>改变登陆组</font><br>useradd&nbsp; &amp;&nbsp; adduser&nbsp;&nbsp;&nbsp; <font face=宋体>建立新用户</font>&nbsp; ---------&gt; useradd -m test&nbsp; <font face=宋体>自动建立用户的登入目录</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; useradd -m -g pgroup test ---------&gt;<font face=宋体>指定所属级</font><br>/etc/default/useradd&nbsp;&nbsp; <font face=宋体>相关设定</font><br>/etc/login.defs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UID/GID <font face=宋体>有關的設定</font><br>passwd&nbsp;&nbsp;&nbsp; <font face=宋体>更改密码</font> -----------&gt; passwd test<br>usermod&nbsp;&nbsp; <font face=宋体>修改用户帐号</font><br>userdel&nbsp;&nbsp; <font face=宋体>删除帐号</font> -----------&gt;userdel -r test<br>chsh&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>更换登陆系统时使用的</font>SHELL&nbsp;&nbsp; [-l]<font face=宋体>显示可用的</font>SHELL;[-s]<font face=宋体>修改自己的</font>SHELL<br>chfn&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>改变</font>finger<font face=宋体>指令显示的信息</font><br>finger&nbsp;&nbsp;&nbsp; <font face=宋体>查找并显示用户信息</font><br>id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示用户的</font>ID -----------&gt;&nbsp; id test<br>groupadd&nbsp;&nbsp; <font face=宋体>添加组</font><br>groupmod&nbsp;&nbsp; <font face=宋体>与</font>usermod<font face=宋体>类似</font><br>groupdel&nbsp;&nbsp; <font face=宋体>删除组</font><br>su test&nbsp;&nbsp;&nbsp; <font face=宋体>更改用户</font>&nbsp;&nbsp; su -&nbsp;&nbsp;&nbsp; <font face=宋体>进入</font>root,<font face=宋体>且使用</font>root<font face=宋体>的环境变量</font><br>sudo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>以其他身份来执行指令</font><br>visudo&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>编辑</font>/etc/sudoers&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>加入一行『</font> test ALL=(ALL) ALL <font face=宋体>』</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %wheel ALL = (ALL) ALL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>系统里所有</font>wheel<font face=宋体>群组的用户都可用</font>sudo<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %wheel ALL = (ALL) NOPASSWD: ALL&nbsp;&nbsp;&nbsp;&nbsp; wheel<font face=宋体>群组所有用户都不用密码</font>NOPASSWD<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; User_Alias ADMPW = vbird, dmtsai, vbird1, vbird3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>加入</font>ADMPW<font face=宋体>组</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ADMPW ALL = NOPASSWD: !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !/usr/bin/passwd root&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>可以更改使用者密码</font>,<font face=宋体>但不能更改</font>root<font face=宋体>密码</font> (<font face=宋体>在指令前面加入</font> ! <font face=宋体>代表不可</font>)<br>PAM (Pluggable Authentication Modules, <font face=宋体>嵌入式模組</font>)<br>who &amp; w&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>看谁在线</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>last&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>最近登陆主机的信息</font><br>lastlog&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>最近登入的時間</font>&nbsp;&nbsp;&nbsp; <font face=宋体>读取</font> /var/log/lastlog <br>talk&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>与其他用户交谈</font><br>write&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>发送信息</font>&nbsp;&nbsp;&nbsp; write test&nbsp;&nbsp; [ctrl]+d <font face=宋体>发送</font><br>mesg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>设置终端机的写入权限</font>&nbsp;&nbsp;&nbsp; mesg n <font face=宋体>禁止接收</font>&nbsp;&nbsp;&nbsp;&nbsp; mesg y <br>wall&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>向所有用户发送信息</font>&nbsp;&nbsp;&nbsp; wall this is q test<br>mail&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>写</font>mail&nbsp;&nbsp; <br>/etc/default/useradd&nbsp;&nbsp;&nbsp; <font face=宋体>家目录默认设置</font></div>
<div>quota&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示磁盘已使用的空间与限制</font>&nbsp;&nbsp;&nbsp;&nbsp; quota -guvs -----&gt;<font face=宋体>秀出目前</font> root <font face=宋体>自己的</font> quota <font face=宋体>限制值</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; quota -vu&nbsp;&nbsp; <font face=宋体>查询</font><br>quotacheck&nbsp;&nbsp; <font face=宋体>检查磁盘的使用空间与限制</font>&nbsp;&nbsp;&nbsp;&nbsp; quotacheck -avug&nbsp; -----&gt;<font face=宋体>將所有的在</font> /etc/mtab <font face=宋体>內，含有</font> quota <font face=宋体>支援的</font> partition <font face=宋体>進行掃瞄</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-m] <font face=宋体>强制扫描</font>&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; quota<font face=宋体>一定要是独立的分区</font>,<font face=宋体>要有</font>quota.user<font face=宋体>和</font>quota.group<font face=宋体>两件文件</font>,<font face=宋体>在</font>/etc/fstab<font face=宋体>添加一句</font>:<br>&nbsp;&nbsp;&nbsp;&nbsp; /dev/hda3 /home ext3 defaults,usrquota,grpquota 1 2<br>&nbsp;&nbsp;&nbsp;&nbsp; chmod 600 quota*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>设置完成</font>,<font face=宋体>重启生效</font><br>edquota&nbsp;&nbsp;&nbsp; <font face=宋体>编辑用户或群组的</font>quota&nbsp; [u]<font face=宋体>用户</font>,[g]<font face=宋体>群组</font>,[p]<font face=宋体>复制</font>,[t]<font face=宋体>设置宽限期限</font> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edquota -a yang&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edquota -p yang -u young -----&gt;<font face=宋体>复制</font>&nbsp;&nbsp;&nbsp; <br>quotaon&nbsp;&nbsp;&nbsp; <font face=宋体>开启磁盘空间限制</font>&nbsp;&nbsp;&nbsp;&nbsp; quotaon -auvg --------&gt;<font face=宋体>啟動所有的具有</font> quota <font face=宋体>的</font> filesystem<br>quotaoff&nbsp;&nbsp; <font face=宋体>关闭磁盘空间限制</font>&nbsp;&nbsp;&nbsp;&nbsp; quotaoff -a&nbsp; --------&gt;<font face=宋体>關閉了</font> quota <font face=宋体>的限制</font><br>repquota -av&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>查閱系統內所有的具有</font> quota <font face=宋体>的</font> filesystem <font face=宋体>的限值狀態</font></div>
<div>Quota <font face=宋体>從開始準備</font> filesystem <font face=宋体>的支援到整個設定結束的主要的步驟大概是：</font><br>1<font face=宋体>、設定</font> partition <font face=宋体>的</font> filesystem <font face=宋体>支援</font> quota <font face=宋体>參數：</font><br><font face=宋体>由於</font> quota <font face=宋体>必須要讓</font> partition <font face=宋体>上面的</font> filesystem <font face=宋体>支援才行，一般來說，</font> <font face=宋体>支援度最好的是</font> ext2/ext3 <font face=宋体>，</font><br><font face=宋体>其他的</font> filesystem <font face=宋体>類型鳥哥我是沒有試過啦！</font> <font face=宋体>啟動</font> filesystem <font face=宋体>支援</font> quota <font face=宋体>最簡單就是編輯</font> /etc/fstab <font face=宋体>，</font><br><font face=宋体>使得準備要開放的</font> quota <font face=宋体>磁碟可以支援</font> quota <font face=宋体>囉；</font><br>2<font face=宋体>、建立</font> quota <font face=宋体>記錄檔：</font><br><font face=宋体>剛剛前面講過，整個</font> quota <font face=宋体>進行磁碟限制值記錄的檔案是</font> aquota.user/aquota.group<font face=宋体>，</font> <br><font face=宋体>要建立這兩個檔案就必須要先利用</font> quotacheck <font face=宋体>掃瞄才行喔！</font><br>3<font face=宋体>、編輯</font> quota <font face=宋体>限制值資料：</font><br><font face=宋体>再來就是使用</font> edquota <font face=宋体>來編輯每個使用者或群組的可使用空間囉；</font><br>4<font face=宋体>、重新掃瞄與啟動</font> quota <font face=宋体>：</font><br><font face=宋体>設定好</font> quota <font face=宋体>之後，建議可以再進行一次</font> quotacheck <font face=宋体>，然後再以</font> quotaon <font face=宋体>來啟動吧！</font></div>
<div><br><font face=宋体>开机流程简介</font><br>1<font face=宋体>、載入</font> BIOS <font face=宋体>的硬體資訊，並取得第一個開機裝置的代號；</font> <br>2<font face=宋体>、讀取第一個開機裝置的</font> MBR <font face=宋体>的</font> boot Loader (<font face=宋体>亦即是</font> lilo, grub, spfdisk <font face=宋体>等等</font>) <font face=宋体>的開機資訊；</font> <br>3<font face=宋体>、載入</font> Kernel <font face=宋体>作業系統核心資訊，</font> Kernel <font face=宋体>開始解壓縮，並且嘗試驅動所有硬體裝置；</font> <br>4<font face=宋体>、</font>Kernel <font face=宋体>執行</font> init <font face=宋体>程式並取得</font> run-level <font face=宋体>資訊；</font> <br>5<font face=宋体>、</font>init <font face=宋体>執行</font> /etc/rc.d/rc.sysinit <font face=宋体>檔案；</font> <br>6<font face=宋体>、啟動核心的外掛模組</font> (/etc/modprobe.conf)<font face=宋体>；</font> <br>7<font face=宋体>、</font>init <font face=宋体>執行</font> run-level <font face=宋体>的各個批次檔</font>( Scripts )<font face=宋体>；</font> <br>8<font face=宋体>、</font>init <font face=宋体>執行</font> /etc/rc.d/rc.local <font face=宋体>檔案；</font> <br>9<font face=宋体>、執行</font> /bin/login <font face=宋体>程式，並等待使用者登入；</font> <br>10<font face=宋体>、登入之後開始以</font> Shell <font face=宋体>控管主機。</font> </div>
<div><font face=宋体>在</font>/etc/rc.d/rc3.d<font face=宋体>內</font>,<font face=宋体>以</font>S<font face=宋体>开头的为开机启动</font>,<font face=宋体>以</font>K<font face=宋体>开头的为关闭</font>,<font face=宋体>接着的数字代表执行顺序</font></div>
<div>GRUB vga<font face=宋体>设定</font><br><font face=宋体>彩度</font>\<font face=宋体>解析度</font>&nbsp; 640x480&nbsp; 800x600&nbsp; 1024x768&nbsp; 1280x1024&nbsp;&nbsp; bit <br>&nbsp;&nbsp;&nbsp; 256&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 769&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 771&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 773&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 775&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8 bit <br>&nbsp;&nbsp; 32768&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 784&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 787&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 790&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 793&nbsp;&nbsp;&nbsp;&nbsp; 15 bit <br>&nbsp;&nbsp; 65536&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 785&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 788&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 791&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 794&nbsp;&nbsp;&nbsp;&nbsp; 16 bit <br>&nbsp;&nbsp; 16.8M&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 786&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 789&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 795&nbsp;&nbsp;&nbsp;&nbsp; 32 bit </div>
<div><br>./configure&nbsp;&nbsp;&nbsp; <font face=宋体>检查系统信息</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ./configure --help | more&nbsp; <font face=宋体>帮助信息</font><br>make clean&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>清除之前留下的文件</font><br>make&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>编译</font><br>make install&nbsp;&nbsp; <font face=宋体>安装</font></div>
<div>rpm -q&nbsp; -----&gt;<font face=宋体>查询是否安装</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rpm -ql ------&gt;<font face=宋体>查询该套件所有的目录</font><br>rpm -qi -----&gt;<font face=宋体>查询套件的说明资料</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rpm -qc[d] -----&gt;<font face=宋体>设定档与说明档</font><br>rpm -ivh&nbsp; ----&gt;<font face=宋体>安装</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rpm -V&nbsp; --------&gt;<font face=宋体>查看套件有否更动过</font><br>rpm -e&nbsp; ------&gt;<font face=宋体>删除</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rpm -Uvh -------&gt;<font face=宋体>升级安装</font>&nbsp; <br>--nodeps -----&gt;<font face=宋体>强行安装</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --test -----&gt;<font face=宋体>测试安装</font></div>
</div>
<div><font size=3><font face="Times New Roman"></font></font>转&nbsp;<a href="http://blog.chinaunix.net/u/30619/showart.php?id=249558">http://blog.chinaunix.net/u/30619/showart.php?id=249558</a></div>
<div></div>
</div>
<img src ="http://www.blogjava.net/xixidabao/aggbug/136537.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2007-08-14 00:21 <a href="http://www.blogjava.net/xixidabao/archive/2007/08/14/136537.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java面试笔试题大汇总 ~很全面</title><link>http://www.blogjava.net/xixidabao/archive/2007/06/01/121279.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Thu, 31 May 2007 18:56:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2007/06/01/121279.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: java面试笔试题大汇总&nbsp;java面试笔试题大汇总&nbsp;&nbsp;第一，谈谈final, finally, finalize的区别。 　　最常被问到。　　 　　第二，Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类，是否可以implements(实现)interface(接口)?　　 　　第三，Static Nest...&nbsp;&nbsp;<a href='http://www.blogjava.net/xixidabao/archive/2007/06/01/121279.html'>阅读全文</a><img src ="http://www.blogjava.net/xixidabao/aggbug/121279.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2007-06-01 02:56 <a href="http://www.blogjava.net/xixidabao/archive/2007/06/01/121279.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网上搜集的java问题</title><link>http://www.blogjava.net/xixidabao/archive/2007/04/14/110597.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Sat, 14 Apr 2007 02:13:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2007/04/14/110597.html</guid><description><![CDATA[<p>1，看看API，在Integer类里面有转成 16进制，8进制和2进制的函数 16进制 Integer.toHexString(int i) 8进制 Integer.toOctalString(int i) 2进制 Integer.toBinaryString(int i) </p>
<p>int i=100; String binStr=Integer.toBinaryString(i); String otcStr=Integer.toOctalString(i); String hexStr=Integer.toHexString(i); System.out.println(binStr); System.out.println(otcStr); System.out.println(hexStr); </p>
<p>2，java 如何实现程序的自动更新，有例子最好了</p>
<p>做一个线程 过一段时间 就连接指定的远程服务器 看最新版本号 与本地当前版本号是不是一致 是的话 就弹出窗口 提示用户 用户确认就 自动下载下来 然后更新原来的class 再启动 过程就是这样 自己写一个小小的代码测试一下就可以 </p>
<img src ="http://www.blogjava.net/xixidabao/aggbug/110597.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2007-04-14 10:13 <a href="http://www.blogjava.net/xixidabao/archive/2007/04/14/110597.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>内存管理内幕</title><link>http://www.blogjava.net/xixidabao/archive/2007/04/03/108120.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Tue, 03 Apr 2007 01:33:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2007/04/03/108120.html</guid><description><![CDATA[<p><a href="http://www.ibm.com/developerworks/cn/linux/l-memory/#author">Jonathan Bartlett</a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#106;&#111;&#104;&#110;&#110;&#121;&#98;&#64;&#101;&#115;&#107;&#105;&#109;&#111;&#46;&#99;&#111;&#109;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#20869;&#23384;&#31649;&#29702;&#20869;&#24149;">johnnyb@eskimo.com</a>), 技术总监, New Media Worx<br></p>
<p>2004 年 11 月 29 日</p>
<blockquote>本文将对 Linux&#8482; 程序员可以使用的内存管理技术进行概述，虽然关注的重点是 C 语言，但同样也适用于其他语言。文中将为您提供如何管理内存的细节，然后将进一步展示如何手工管理内存，如何使用引用计数或者内存池来半手工地管理内存，以及如何使用垃圾收集自动管理内存。</blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
<p><a name=N10046><span class=atitle>为什么必须管理内存</span></a></p>
<p>内存管理是计算机编程最为基本的领域之一。在很多脚本语言中，您不必担心内存是如何管理的，这并不能使得内存管理的重要性有一点点降低。对实际编程来说，理解您的内存管理器的能力与局限性至关重要。在大部分系统语言中，比如 C 和 C++，您必须进行内存管理。本文将介绍手工的、半手工的以及自动的内存管理实践的基本概念。 </p>
<p>追溯到在 Apple II 上进行汇编语言编程的时代，那时内存管理还不是个大问题。您实际上在运行整个系统。系统有多少内存，您就有多少内存。您甚至不必费心思去弄明白它有多少内存，因为每一台机器的内存数量都相同。所以，如果内存需要非常固定，那么您只需要选择一个内存范围并使用它即可。 </p>
<p>不过，即使是在这样一个简单的计算机中，您也会有问题，尤其是当您不知道程序的每个部分将需要多少内存时。如果您的空间有限，而内存需求是变化的，那么您需要一些方法来满足这些需求：
<ul>
    <li>确定您是否有足够的内存来处理数据。
    <li>从可用的内存中获取一部分内存。
    <li>向可用内存池（pool）中返回部分内存，以使其可以由程序的其他部分或者其他程序使用。 </li>
</ul>
<p>&nbsp;</p>
<p>实现这些需求的程序库称为 <em>分配程序（allocators）</em>，因为它们负责分配和回收内存。程序的动态性越强，内存管理就越重要，您的内存分配程序的选择也就更重要。让我们来了解可用于内存管理的不同方法，它们的好处与不足，以及它们最适用的情形。 </p>
<br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
        </tr>
    </tbody>
</table>
<table class=no-print cellSpacing=0 cellPadding=0 align=right>
    <tbody>
        <tr align=right>
            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
            <table cellSpacing=0 cellPadding=0 border=0>
                <tbody>
                    <tr>
                        <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                        <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/l-memory/#main"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name=N10068><span class=atitle>C 风格的内存分配程序</span></a></p>
<p>C 编程语言提供了两个函数来满足我们的三个需求：
<ul>
    <li><strong>malloc：</strong>该函数分配给定的字节数，并返回一个指向它们的指针。如果没有足够的可用内存，那么它返回一个空指针。
    <li><strong>free：</strong>该函数获得指向由 <code>malloc</code> 分配的内存片段的指针，并将其释放，以便以后的程序或操作系统使用（实际上，一些 <code>malloc</code> 实现只能将内存归还给程序，而无法将内存归还给操作系统）。 </li>
</ul>
<p>&nbsp;</p>
<p><a name=N10089><span class=smalltitle>物理内存和虚拟内存</span></a></p>
<p>要理解内存在程序中是如何分配的，首先需要理解如何将内存从操作系统分配给程序。计算机上的每一个进程都认为自己可以访问所有的物理内存。显然，由于同时在运行多个程序，所以每个进程不可能拥有全部内存。实际上，这些进程使用的是 <em>虚拟内存</em>。 </p>
<p>只是作为一个例子，让我们假定您的程序正在访问地址为 629 的内存。不过，虚拟内存系统不需要将其存储在位置为 629 的 RAM 中。实际上，它甚至可以不在 RAM 中 —— 如果物理 RAM 已经满了，它甚至可能已经被转移到硬盘上！由于这类地址不必反映内存所在的物理位置，所以它们被称为虚拟内存。操作系统维持着一个虚拟地址到物理地址的转换的表，以便计算机硬件可以正确地响应地址请求。并且，如果地址在硬盘上而不是在 RAM 中，那么操作系统将暂时停止您的进程，将其他内存转存到硬盘中，从硬盘上加载被请求的内存，然后再重新启动您的进程。这样，每个进程都获得了自己可以使用的地址空间，可以访问比您物理上安装的内存更多的内存。 </p>
<p>在 32-位 x86 系统上，每一个进程可以访问 4 GB 内存。现在，大部分人的系统上并没有 4 GB 内存，即使您将 swap 也算上， <em>每个进程</em>所使用的内存也肯定少于 4 GB。因此，当加载一个进程时，它会得到一个取决于某个称为 <em>系统中断点（system break）</em>的特定地址的初始内存分配。该地址之后是未被映射的内存 —— 用于在 RAM 或者硬盘中没有分配相应物理位置的内存。因此，如果一个进程运行超出了它初始分配的内存，那么它必须请求操作系统&#8220;映射进来（map in）&#8221;更多的内存。（映射是一个表示一一对应关系的数学术语 —— 当内存的虚拟地址有一个对应的物理地址来存储内存内容时，该内存将被映射。） </p>
<p>基于 UNIX 的系统有两个可映射到附加内存中的基本系统调用：
<ul>
    <li><strong>brk：</strong> <code>brk()</code> 是一个非常简单的系统调用。还记得系统中断点吗？该位置是进程映射的内存边界。 <code>brk()</code> 只是简单地将这个位置向前或者向后移动，就可以向进程添加内存或者从进程取走内存。
    <li><strong>mmap：</strong> <code>mmap()</code>，或者说是&#8220;内存映像&#8221;，类似于 <code>brk()</code>，但是更为灵活。首先，它可以映射任何位置的内存，而不单单只局限于进程。其次，它不仅可以将虚拟地址映射到物理的 RAM 或者 swap，它还可以将它们映射到文件和文件位置，这样，读写内存将对文件中的数据进行读写。不过，在这里，我们只关心 <code>mmap</code> 向进程添加被映射的内存的能力。 <code>munmap()</code> 所做的事情与 <code>mmap()</code> 相反。 </li>
</ul>
<p>&nbsp;</p>
<p>如您所见， <code>brk()</code> 或者 <code>mmap()</code> 都可以用来向我们的进程添加额外的虚拟内存。在我们的例子中将使用 <code>brk()</code>，因为它更简单，更通用。 </p>
<p><a name=N100DE><span class=smalltitle>实现一个简单的分配程序</span></a></p>
<p>如果您曾经编写过很多 C 程序，那么您可能曾多次使用过 <code>malloc()</code> 和 <code>free()</code>。不过，您可能没有用一些时间去思考它们在您的操作系统中是如何实现的。本节将向您展示 <code>malloc</code> 和 <code>free</code> 的一个最简化实现的代码，来帮助说明管理内存时都涉及到了哪些事情。 </p>
<p>要试着运行这些示例，需要先 <a href="http://www.ibm.com/developerworks/cn/linux/l-memory/sidefile.html">复制本代码清单</a>，并将其粘贴到一个名为 malloc.c 的文件中。接下来，我将一次一个部分地对该清单进行解释。 </p>
<p>在大部分操作系统中，内存分配由以下两个简单的函数来处理： </p>
<ul>
    <li><code>void *malloc(long numbytes)</code>：该函数负责分配 <code>numbytes</code> 大小的内存，并返回指向第一个字节的指针。
    <li><code>void free(void *firstbyte)</code>：如果给定一个由先前的 <code>malloc</code> 返回的指针，那么该函数会将分配的空间归还给进程的&#8220;空闲空间&#8221;。 </li>
</ul>
<p><code>malloc_init</code> 将是初始化内存分配程序的函数。它要完成以下三件事：将分配程序标识为已经初始化，找到系统中最后一个有效内存地址，然后建立起指向我们管理的内存的指针。这三个变量都是全局变量： </p>
<br><br><a name=N10124><strong>清单 1. 我们的简单分配程序的全局变量</strong></a><br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>            int has_initialized = 0;
            void *managed_memory_start;
            void *last_valid_address;
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>如前所述，被映射的内存的边界（最后一个有效地址）常被称为系统中断点或者 <em>当前中断点</em>。在很多 UNIX&#174; 系统中，为了指出当前系统中断点，必须使用 <code>sbrk(0)</code> 函数。 <code>sbrk</code> 根据参数中给出的字节数移动当前系统中断点，然后返回新的系统中断点。使用参数 <code>0</code> 只是返回当前中断点。这里是我们的 <code>malloc</code> 初始化代码，它将找到当前中断点并初始化我们的变量： </p>
<br><br><a name=N10144><strong>清单 2. 分配程序初始化函数</strong></a><br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>            /* Include the sbrk function */
            #include &lt;unistd.h&gt;
            void malloc_init()
            {
            /* grab the last valid address from the OS */
            last_valid_address = sbrk(0);
            /* we don't have any memory to manage yet, so
            *just set the beginning to be last_valid_address
            */
            managed_memory_start = last_valid_address;
            /* Okay, we're initialized and ready to go */
            has_initialized = 1;
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>现在，为了完全地管理内存，我们需要能够追踪要分配和回收哪些内存。在对内存块进行了 <code>free</code> 调用之后，我们需要做的是诸如将它们标记为未被使用的等事情，并且，在调用 <code>malloc</code> 时，我们要能够定位未被使用的内存块。因此， <code>malloc</code> 返回的每块内存的起始处首先要有这个结构： </p>
<br><br><a name=N1015D><strong>清单 3. 内存控制块结构定义</strong></a><br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>            struct mem_control_block {
            int is_available;
            int size;
            };
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>现在，您可能会认为当程序调用 <code>malloc</code> 时这会引发问题 —— 它们如何知道这个结构？答案是它们不必知道；在返回指针之前，我们会将其移动到这个结构之后，把它隐藏起来。这使得返回的指针指向没有用于任何其他用途的内存。那样，从调用程序的角度来看，它们所得到的全部是空闲的、开放的内存。然后，当通过 <code>free()</code> 将该指针传递回来时，我们只需要倒退几个内存字节就可以再次找到这个结构。 </p>
<p>在讨论分配内存之前，我们将先讨论释放，因为它更简单。为了释放内存，我们必须要做的惟一一件事情就是，获得我们给出的指针，回退 <code>sizeof(struct mem_control_block)</code> 个字节，并将其标记为可用的。这里是对应的代码： </p>
<br><br><a name=N10179><strong>清单 4. 解除分配函数</strong></a><br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>            void free(void *firstbyte) {
            struct mem_control_block *mcb;
            /* Backup from the given pointer to find the
            * mem_control_block
            */
            mcb = firstbyte - sizeof(struct mem_control_block);
            /* Mark the block as being available */
            mcb-&gt;is_available = 1;
            /* That's It!  We're done. */
            return;
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>如您所见，在这个分配程序中，内存的释放使用了一个非常简单的机制，在固定时间内完成内存释放。分配内存稍微困难一些。以下是该算法的略述： </p>
<br><br><a name=N10186><strong>清单 5. 主分配程序的伪代码</strong></a><br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>            1. If our allocator has not been initialized, initialize it.
            2. Add sizeof(struct mem_control_block) to the size requested.
            3. start at managed_memory_start.
            4. Are we at last_valid address?
            5. If we are:
            A. We didn't find any existing space that was large enough
            -- ask the operating system for more and return that.
            6. Otherwise:
            A. Is the current space available (check is_available from
            the mem_control_block)?
            B. If it is:
            i)   Is it large enough (check "size" from the
            mem_control_block)?
            ii)  If so:
            a. Mark it as unavailable
            b. Move past mem_control_block and return the
            pointer
            iii) Otherwise:
            a. Move forward "size" bytes
            b. Go back go step 4
            C. Otherwise:
            i)   Move forward "size" bytes
            ii)  Go back to step 4
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>我们主要使用连接的指针遍历内存来寻找开放的内存块。这里是代码： </p>
<br><br><a name=N10193><strong>清单 6. 主分配程序</strong></a><br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>            void *malloc(long numbytes) {
            /* Holds where we are looking in memory */
            void *current_location;
            /* This is the same as current_location, but cast to a
            * memory_control_block
            */
            struct mem_control_block *current_location_mcb;
            /* This is the memory location we will return.  It will
            * be set to 0 until we find something suitable
            */
            void *memory_location;
            /* Initialize if we haven't already done so */
            if(! has_initialized) 	{
            malloc_init();
            }
            /* The memory we search for has to include the memory
            * control block, but the users of malloc don't need
            * to know this, so we'll just add it in for them.
            */
            numbytes = numbytes + sizeof(struct mem_control_block);
            /* Set memory_location to 0 until we find a suitable
            * location
            */
            memory_location = 0;
            /* Begin searching at the start of managed memory */
            current_location = managed_memory_start;
            /* Keep going until we have searched all allocated space */
            while(current_location != last_valid_address)
            {
            /* current_location and current_location_mcb point
            * to the same address.  However, current_location_mcb
            * is of the correct type, so we can use it as a struct.
            * current_location is a void pointer so we can use it
            * to calculate addresses.
            */
            current_location_mcb =
            (struct mem_control_block *)current_location;
            if(current_location_mcb-&gt;is_available)
            {
            if(current_location_mcb-&gt;size &gt;= numbytes)
            {
            /* Woohoo!  We've found an open,
            * appropriately-size location.
            */
            /* It is no longer available */
            current_location_mcb-&gt;is_available = 0;
            /* We own it */
            memory_location = current_location;
            /* Leave the loop */
            break;
            }
            }
            /* If we made it here, it's because the Current memory
            * block not suitable; move to the next one
            */
            current_location = current_location +
            current_location_mcb-&gt;size;
            }
            /* If we still don't have a valid location, we'll
            * have to ask the operating system for more memory
            */
            if(! memory_location)
            {
            /* Move the program break numbytes further */
            sbrk(numbytes);
            /* The new memory will be where the last valid
            * address left off
            */
            memory_location = last_valid_address;
            /* We'll move the last valid address forward
            * numbytes
            */
            last_valid_address = last_valid_address + numbytes;
            /* We need to initialize the mem_control_block */
            current_location_mcb = memory_location;
            current_location_mcb-&gt;is_available = 0;
            current_location_mcb-&gt;size = numbytes;
            }
            /* Now, no matter what (well, except for error conditions),
            * memory_location has the address of the memory, including
            * the mem_control_block
            */
            /* Move the pointer past the mem_control_block */
            memory_location = memory_location + sizeof(struct mem_control_block);
            /* Return the pointer */
            return memory_location;
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>这就是我们的内存管理器。现在，我们只需要构建它，并在程序中使用它即可。 </p>
<p>运行下面的命令来构建 <code>malloc</code> 兼容的分配程序（实际上，我们忽略了 <code>realloc()</code> 等一些函数，不过， <code>malloc()</code> 和 <code>free()</code> 才是最主要的函数）： </p>
<br><br><a name=N101B3><strong>清单 7. 编译分配程序</strong></a><br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>            gcc -shared -fpic malloc.c -o malloc.so
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>该程序将生成一个名为 <em>malloc.so</em> 的文件，它是一个包含有我们的代码的共享库。 </p>
<p>在 UNIX 系统中，现在您可以用您的分配程序来取代系统的 <code>malloc()</code>，做法如下： </p>
<br><br><a name=N101CA><strong>清单 8. 替换您的标准的 malloc</strong></a><br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>            LD_PRELOAD=/path/to/malloc.so
            export LD_PRELOAD
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p><code>LD_PRELOAD</code> 环境变量使动态链接器在加载任何可执行程序之前，先加载给定的共享库的符号。它还为特定库中的符号赋予优先权。因此，从现在起，该会话中的任何应用程序都将使用我们的 <code>malloc()</code>，而不是只有系统的应用程序能够使用。有一些应用程序不使用 <code>malloc()</code>，不过它们是例外。其他使用 <code>realloc()</code> 等其他内存管理函数的应用程序，或者错误地假定 <code>malloc()</code> 内部行为的那些应用程序，很可能会崩溃。ash shell 似乎可以使用我们的新 <code>malloc()</code> 很好地工作。 </p>
<p>如果您想确保 <code>malloc()</code> 正在被使用，那么您应该通过向函数的入口点添加 <code>write()</code> 调用来进行测试。 </p>
<p>我们的内存管理器在很多方面都还存在欠缺，但它可以有效地展示内存管理需要做什么事情。它的某些缺点包括：
<ul>
    <li>由于它对系统中断点（一个全局变量）进行操作，所以它不能与其他分配程序或者 <code>mmap</code> 一起使用。
    <li>当分配内存时，在最坏的情形下，它将不得不遍历 <em>全部</em>进程内存；其中可能包括位于硬盘上的很多内存，这意味着操作系统将不得不花时间去向硬盘移入数据和从硬盘中移出数据。
    <li>没有很好的内存不足处理方案（ <code>malloc</code> 只假定内存分配是成功的）。
    <li>它没有实现很多其他的内存函数，比如 <code>realloc()</code>。
    <li>由于 <code>sbrk()</code> 可能会交回比我们请求的更多的内存，所以在堆（heap）的末端会遗漏一些内存。
    <li>虽然 <code>is_available</code> 标记只包含一位信息，但它要使用完整的 4-字节 的字。
    <li>分配程序不是线程安全的。
    <li>分配程序不能将空闲空间拼合为更大的内存块。
    <li>分配程序的过于简单的匹配算法会导致产生很多潜在的内存碎片。
    <li>我确信还有很多其他问题。这就是为什么它只是一个例子! </li>
</ul>
<p>&nbsp;</p>
<p><a name=N10232><span class=smalltitle>其他 malloc 实现</span></a></p>
<p><code>malloc()</code> 的实现有很多，这些实现各有优点与缺点。在设计一个分配程序时，要面临许多需要折衷的选择，其中包括：
<ul>
    <li>分配的速度。
    <li>回收的速度。
    <li>有线程的环境的行为。
    <li>内存将要被用光时的行为。
    <li>局部缓存。
    <li>簿记（Bookkeeping）内存开销。
    <li>虚拟内存环境中的行为。
    <li>小的或者大的对象。
    <li>实时保证。 </li>
</ul>
<p>&nbsp;</p>
<p>每一个实现都有其自身的优缺点集合。在我们的简单的分配程序中，分配非常慢，而回收非常快。另外，由于它在使用虚拟内存系统方面较差，所以它最适于处理大的对象。 </p>
<p>还有其他许多分配程序可以使用。其中包括：
<ul>
    <li><strong>Doug Lea Malloc：</strong>Doug Lea Malloc 实际上是完整的一组分配程序，其中包括 Doug Lea 的原始分配程序，GNU libc 分配程序和 <code>ptmalloc</code>。 Doug Lea 的分配程序有着与我们的版本非常类似的基本结构，但是它加入了索引，这使得搜索速度更快，并且可以将多个没有被使用的块组合为一个大的块。它还支持缓存，以便更快地再次使用最近释放的内存。 <code>ptmalloc</code> 是 Doug Lea Malloc 的一个扩展版本，支持多线程。在本文后面的 <a href="http://www.ibm.com/developerworks/cn/linux/l-memory/#resources">参考资料</a>部分中，有一篇描述 Doug Lea 的 Malloc 实现的文章。
    <li><strong>BSD Malloc：</strong>BSD Malloc 是随 4.2 BSD 发行的实现，包含在 FreeBSD 之中，这个分配程序可以从预先确实大小的对象构成的池中分配对象。它有一些用于对象大小的 size 类，这些对象的大小为 2 的若干次幂减去某一常数。所以，如果您请求给定大小的一个对象，它就简单地分配一个与之匹配的 size 类。这样就提供了一个快速的实现，但是可能会浪费内存。在 <a href="http://www.ibm.com/developerworks/cn/linux/l-memory/#resources">参考资料</a>部分中，有一篇描述该实现的文章。
    <li><strong>Hoard：编写 </strong>Hoard 的目标是使内存分配在多线程环境中进行得非常快。因此，它的构造以锁的使用为中心，从而使所有进程不必等待分配内存。它可以显著地加快那些进行很多分配和回收的多线程进程的速度。在 <a href="http://www.ibm.com/developerworks/cn/linux/l-memory/#resources">参考资料</a>部分中，有一篇描述该实现的文章。 </li>
</ul>
<p>&nbsp;</p>
<p>众多可用的分配程序中最有名的就是上述这些分配程序。如果您的程序有特别的分配需求，那么您可能更愿意编写一个定制的能匹配您的程序内存分配方式的分配程序。不过，如果不熟悉分配程序的设计，那么定制分配程序通常会带来比它们解决的问题更多的问题。要获得关于该主题的适当的介绍，请参阅 Donald Knuth 撰写的 <em>The Art of Computer Programming Volume 1: Fundamental Algorithms</em> 中的第 2.5 节&#8220;Dynamic Storage Allocation&#8221;（请参阅 <a href="http://www.ibm.com/developerworks/cn/linux/l-memory/#resources">参考资料</a>中的链接）。它有点过时，因为它没有考虑虚拟内存环境，不过大部分算法都是基于前面给出的函数。 </p>
<p>在 C++ 中，通过重载 <code>operator new()</code>，您可以以每个类或者每个模板为单位实现自己的分配程序。在 Andrei Alexandrescu 撰写的 <em>Modern C++ Design</em> 的第 4 章（&#8220;Small Object Allocation&#8221;）中，描述了一个小对象分配程序（请参阅 <a href="http://www.ibm.com/developerworks/cn/linux/l-memory/#resources">参考资料</a>中的链接）。 </p>
<p><a name=N102A4><span class=smalltitle>基于 malloc() 的内存管理的缺点</span></a></p>
<p>不只是我们的内存管理器有缺点，基于 <code>malloc()</code> 的内存管理器仍然也有很多缺点，不管您使用的是哪个分配程序。对于那些需要保持长期存储的程序使用 <code>malloc()</code> 来管理内存可能会非常令人失望。如果您有大量的不固定的内存引用，经常难以知道它们何时被释放。生存期局限于当前函数的内存非常容易管理，但是对于生存期超出该范围的内存来说，管理内存则困难得多。而且，关于内存管理是由进行调用的程序还是由被调用的函数来负责这一问题，很多 API 都不是很明确。 </p>
<p>因为管理内存的问题，很多程序倾向于使用它们自己的内存管理规则。C++ 的异常处理使得这项任务更成问题。有时好像致力于管理内存分配和清理的代码比实际完成计算任务的代码还要多！因此，我们将研究内存管理的其他选择。 </p>
<br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
        </tr>
    </tbody>
</table>
<table class=no-print cellSpacing=0 cellPadding=0 align=right>
    <tbody>
        <tr align=right>
            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
            <table cellSpacing=0 cellPadding=0 border=0>
                <tbody>
                    <tr>
                        <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                        <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/l-memory/#main"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name=N102B8><span class=atitle>半自动内存管理策略</span></a></p>
<p><a name=N102BF><span class=smalltitle>引用计数</span></a></p>
<p>引用计数是一种 <em>半自动（semi-automated）</em>的内存管理技术，这表示它需要一些编程支持，但是它不需要您确切知道某一对象何时不再被使用。引用计数机制为您完成内存管理任务。 </p>
<p>在引用计数中，所有共享的数据结构都有一个域来包含当前活动&#8220;引用&#8221;结构的次数。当向一个程序传递一个指向某个数据结构指针时，该程序会将引用计数增加 1。实质上，您是在告诉数据结构，它正在被存储在多少个位置上。然后，当您的进程完成对它的使用后，该程序就会将引用计数减少 1。结束这个动作之后，它还会检查计数是否已经减到零。如果是，那么它将释放内存。 </p>
<p>这样做的好处是，您不必追踪程序中某个给定的数据结构可能会遵循的每一条路径。每次对其局部的引用，都将导致计数的适当增加或减少。这样可以防止在使用数据结构时释放该结构。不过，当您使用某个采用引用计数的数据结构时，您必须记得运行引用计数函数。另外，内置函数和第三方的库不会知道或者可以使用您的引用计数机制。引用计数也难以处理发生循环引用的数据结构。 </p>
<p>要实现引用计数，您只需要两个函数 —— 一个增加引用计数，一个减少引用计数并当计数减少到零时释放内存。 </p>
<p>一个示例引用计数函数集可能看起来如下所示： </p>
<br><br><a name=N102DA><strong>清单 9. 基本的引用计数函数</strong></a><br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>            /* Structure Definitions*/
            /* Base structure that holds a refcount */
            struct refcountedstruct
            {
            int refcount;
            }
            /* All refcounted structures must mirror struct
            * refcountedstruct for their first variables
            */
            /* Refcount maintenance functions */
            /* Increase reference count */
            void REF(void *data)
            {
            struct refcountedstruct *rstruct;
            rstruct = (struct refcountedstruct *) data;
            rstruct-&gt;refcount++;
            }
            /* Decrease reference count */
            void UNREF(void *data)
            {
            struct refcountedstruct *rstruct;
            rstruct = (struct refcountedstruct *) data;
            rstruct-&gt;refcount--;
            /* Free the structure if there are no more users */
            if(rstruct-&gt;refcount == 0)
            {
            free(rstruct);
            }
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p><code>REF</code> 和 <code>UNREF</code> 可能会更复杂，这取决于您想要做的事情。例如，您可能想要为多线程程序增加锁，那么您可能想扩展 <code>refcountedstruct</code>，使它同样包含一个指向某个在释放内存之前要调用的函数的指针（类似于面向对象语言中的析构函数 —— 如果您的结构中包含这些指针，那么这是 <em>必需的</em>）。 </p>
<p>当使用 <code>REF</code> 和 <code>UNREF</code> 时，您需要遵守这些指针的分配规则：
<ul>
    <li><code>UNREF</code> 分配前左端指针（left-hand-side pointer）指向的值。
    <li><code>REF</code> 分配后左端指针（left-hand-side pointer）指向的值。 </li>
</ul>
<p>&nbsp;</p>
<p>在传递使用引用计数的结构的函数中，函数需要遵循以下这些规则：
<ul>
    <li>在函数的起始处 REF 每一个指针。
    <li>在函数的结束处 UNREF 第一个指针。 </li>
</ul>
<p>&nbsp;</p>
<p>以下是一个使用引用计数的生动的代码示例： </p>
<br><br><a name=N10322><strong>清单 10. 使用引用计数的示例</strong></a><br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>            /* EXAMPLES OF USAGE */
            /* Data type to be refcounted */
            struct mydata
            {
            int refcount; /* same as refcountedstruct */
            int datafield1; /* Fields specific to this struct */
            int datafield2;
            /* other declarations would go here as appropriate */
            };
            /* Use the functions in code */
            void dosomething(struct mydata *data)
            {
            REF(data);
            /* Process data */
            /* when we are through */
            UNREF(data);
            }
            struct mydata *globalvar1;
            /* Note that in this one, we don't decrease the
            * refcount since we are maintaining the reference
            * past the end of the function call through the
            * global variable
            */
            void storesomething(struct mydata *data)
            {
            REF(data); /* passed as a parameter */
            globalvar1 = data;
            REF(data); /* ref because of Assignment */
            UNREF(data); /* Function finished */
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>由于引用计数是如此简单，大部分程序员都自已去实现它，而不是使用库。不过，它们依赖于 <code>malloc</code> 和 <code>free</code> 等低层的分配程序来实际地分配和释放它们的内存。 </p>
<p>在 Perl 等高级语言中，进行内存管理时使用引用计数非常广泛。在这些语言中，引用计数由语言自动地处理，所以您根本不必担心它，除非要编写扩展模块。由于所有内容都必须进行引用计数，所以这会对速度产生一些影响，但它极大地提高了编程的安全性和方便性。以下是引用计数的益处：
<ul>
    <li>实现简单。
    <li>易于使用。
    <li>由于引用是数据结构的一部分，所以它有一个好的缓存位置。 </li>
</ul>
<p>&nbsp;</p>
<p>不过，它也有其不足之处：
<ul>
    <li>要求您永远不要忘记调用引用计数函数。
    <li>无法释放作为循环数据结构的一部分的结构。
    <li>减缓几乎每一个指针的分配。
    <li>尽管所使用的对象采用了引用计数，但是当使用异常处理（比如 <code>try</code> 或 <code>setjmp()</code>/ <code>longjmp()</code>）时，您必须采取其他方法。
    <li>需要额外的内存来处理引用。
    <li>引用计数占用了结构中的第一个位置，在大部分机器中最快可以访问到的就是这个位置。
    <li>在多线程环境中更慢也更难以使用。 </li>
</ul>
<p>&nbsp;</p>
<p>C++ 可以通过使用 <em>智能指针（smart pointers）</em>来容忍程序员所犯的一些错误，智能指针可以为您处理引用计数等指针处理细节。不过，如果不得不使用任何先前的不能处理智能指针的代码（比如对 C 库的联接），实际上，使用它们的后果通实比不使用它们更为困难和复杂。因此，它通常只是有益于纯 C++ 项目。如果您想使用智能指针，那么您实在应该去阅读 Alexandrescu 撰写的 <em>Modern C++ Design</em> 一书中的&#8220;Smart Pointers&#8221;那一章。 </p>
<p><a name=N10373><span class=smalltitle>内存池</span></a></p>
<p>内存池是另一种半自动内存管理方法。内存池帮助某些程序进行自动内存管理，这些程序会经历一些特定的阶段，而且每个阶段中都有分配给进程的特定阶段的内存。例如，很多网络服务器进程都会分配很多针对每个连接的内存 —— 内存的最大生存期限为当前连接的存在期。Apache 使用了池式内存（pooled memory），将其连接拆分为各个阶段，每个阶段都有自己的内存池。在结束每个阶段时，会一次释放所有内存。 </p>
<p>在池式内存管理中，每次内存分配都会指定内存池，从中分配内存。每个内存池都有不同的生存期限。在 Apache 中，有一个持续时间为服务器存在期的内存池，还有一个持续时间为连接的存在期的内存池，以及一个持续时间为请求的存在期的池，另外还有其他一些内存池。因此，如果我的一系列函数不会生成比连接持续时间更长的数据，那么我就可以完全从连接池中分配内存，并知道在连接结束时，这些内存会被自动释放。另外，有一些实现允许注册 <em>清除函数（cleanup functions）</em>，在清除内存池之前，恰好可以调用它，来完成在内存被清理前需要完成的其他所有任务（类似于面向对象中的析构函数）。 </p>
<p>要在自己的程序中使用池，您既可以使用 GNU libc 的 obstack 实现，也可以使用 Apache 的 Apache Portable Runtime。GNU obstack 的好处在于，基于 GNU 的 Linux 发行版本中默认会包括它们。Apache Portable Runtime 的好处在于它有很多其他工具，可以处理编写多平台服务器软件所有方面的事情。要深入了解 GNU obstack 和 Apache 的池式内存实现，请参阅 <a href="http://www.ibm.com/developerworks/cn/linux/l-memory/#resources">参考资料</a>部分中指向这些实现的文档的链接。 </p>
<p>下面的假想代码列表展示了如何使用 obstack： </p>
<br><br><a name=N1038F><strong>清单 11. obstack 的示例代码</strong></a><br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>            #include &lt;obstack.h&gt;
            #include &lt;stdlib.h&gt;
            /* Example code listing for using obstacks */
            /* Used for obstack macros (xmalloc is
            a malloc function that exits if memory
            is exhausted */
            #define obstack_chunk_alloc xmalloc
            #define obstack_chunk_free free
            /* Pools */
            /* Only permanent allocations should go in this pool */
            struct obstack *global_pool;
            /* This pool is for per-connection data */
            struct obstack *connection_pool;
            /* This pool is for per-request data */
            struct obstack *request_pool;
            void allocation_failed()
            {
            exit(1);
            }
            int main()
            {
            /* Initialize Pools */
            global_pool = (struct obstack *)
            xmalloc (sizeof (struct obstack));
            obstack_init(global_pool);
            connection_pool = (struct obstack *)
            xmalloc (sizeof (struct obstack));
            obstack_init(connection_pool);
            request_pool = (struct obstack *)
            xmalloc (sizeof (struct obstack));
            obstack_init(request_pool);
            /* Set the error handling function */
            obstack_alloc_failed_handler = &amp;allocation_failed;
            /* Server main loop */
            while(1)
            {
            wait_for_connection();
            /* We are in a connection */
            while(more_requests_available())
            {
            /* Handle request */
            handle_request();
            /* Free all of the memory allocated
            * in the request pool
            */
            obstack_free(request_pool, NULL);
            }
            /* We're finished with the connection, time
            * to free that pool
            */
            obstack_free(connection_pool, NULL);
            }
            }
            int handle_request()
            {
            /* Be sure that all object allocations are allocated
            * from the request pool
            */
            int bytes_i_need = 400;
            void *data1 = obstack_alloc(request_pool, bytes_i_need);
            /* Do stuff to process the request */
            /* return */
            return 0;
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>基本上，在操作的每一个主要阶段结束之后，这个阶段的 obstack 会被释放。不过，要注意的是，如果一个过程需要分配持续时间比当前阶段更长的内存，那么它也可以使用更长期限的 obstack，比如连接或者全局内存。传递给 <code>obstack_free()</code> 的 <code>NULL</code> 指出它应该释放 obstack 的全部内容。可以用其他的值，但是它们通常不怎么实用。 </p>
<p>使用池式内存分配的益处如下所示：
<ul>
    <li>应用程序可以简单地管理内存。
    <li>内存分配和回收更快，因为每次都是在一个池中完成的。分配可以在 O(1) 时间内完成，释放内存池所需时间也差不多（实际上是 O(n) 时间，不过在大部分情况下会除以一个大的因数，使其变成 O(1)）。
    <li>可以预先分配错误处理池（Error-handling pools），以便程序在常规内存被耗尽时仍可以恢复。
    <li>有非常易于使用的标准实现。 </li>
</ul>
<p>&nbsp;</p>
<p>池式内存的缺点是： </p>
<ul>
    <li>内存池只适用于操作可以分阶段的程序。
    <li>内存池通常不能与第三方库很好地合作。
    <li>如果程序的结构发生变化，则不得不修改内存池，这可能会导致内存管理系统的重新设计。
    <li>您必须记住需要从哪个池进行分配。另外，如果在这里出错，就很难捕获该内存池。 </li>
</ul>
<br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
        </tr>
    </tbody>
</table>
<table class=no-print cellSpacing=0 cellPadding=0 align=right>
    <tbody>
        <tr align=right>
            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
            <table cellSpacing=0 cellPadding=0 border=0>
                <tbody>
                    <tr>
                        <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                        <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/l-memory/#main"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name=N103C5><span class=atitle>垃圾收集</span></a></p>
<p><em>垃圾收集（Garbage collection）</em>是全自动地检测并移除不再使用的数据对象。垃圾收集器通常会在当可用内存减少到少于一个具体的阈值时运行。通常，它们以程序所知的可用的一组&#8220;基本&#8221;数据 —— 栈数据、全局变量、寄存器 —— 作为出发点。然后它们尝试去追踪通过这些数据连接到每一块数据。收集器找到的都是有用的数据；它没有找到的就是垃圾，可以被销毁并重新使用这些无用的数据。为了有效地管理内存，很多类型的垃圾收集器都需要知道数据结构内部指针的规划，所以，为了正确运行垃圾收集器，它们必须是语言本身的一部分。 </p>
<p><a name=N103D2><span class=smalltitle>收集器的类型</span></a></p>
<p>
<ul>
    <li><strong>复制（copying）：</strong> 这些收集器将内存存储器分为两部分，只允许数据驻留在其中一部分上。它们定时地从&#8220;基本&#8221;的元素开始将数据从一部分复制到另一部分。内存新近被占用的部分现在成为活动的，另一部分上的所有内容都认为是垃圾。另外，当进行这项复制操作时，所有指针都必须被更新为指向每个内存条目的新位置。因此，为使用这种垃圾收集方法，垃圾收集器必须与编程语言集成在一起。
    <li><strong>标记并清理（Mark and sweep）：</strong>每一块数据都被加上一个标签。不定期的，所有标签都被设置为 0，收集器从&#8220;基本&#8221;的元素开始遍历数据。当它遇到内存时，就将标签标记为 1。最后没有被标记为 1 的所有内容都认为是垃圾，以后分配内存时会重新使用它们。
    <li><strong>增量的（Incremental）：</strong>增量垃圾收集器不需要遍历全部数据对象。因为在收集期间的突然等待，也因为与访问所有当前数据相关的缓存问题（所有内容都不得不被页入（page-in）），遍历所有内存会引发问题。增量收集器避免了这些问题。
    <li><strong>保守的（Conservative）：</strong>保守的垃圾收集器在管理内存时不需要知道与数据结构相关的任何信息。它们只查看所有数据类型，并假定它们 <em>可以</em>全部都是指针。所以，如果一个字节序列可以是一个指向一块被分配的内存的指针，那么收集器就将其标记为正在被引用。有时没有被引用的内存会被收集，这样会引发问题，例如，如果一个整数域中包含一个值，该值是已分配内存的地址。不过，这种情况极少发生，而且它只会浪费少量内存。保守的收集器的优势是，它们可以与任何编程语言相集成。 </li>
</ul>
<p>&nbsp;</p>
<p>Hans Boehm 的保守垃圾收集器是可用的最流行的垃圾收集器之一，因为它是免费的，而且既是保守的又是增量的，可以使用 <code>--enable-redirect-malloc</code> 选项来构建它，并且可以将它用作系统分配程序的简易替代者（drop-in replacement）（用 <code>malloc</code>/ <code>free</code> 代替它自己的 API）。实际上，如果这样做，您就可以使用与我们在示例分配程序中所使用的相同的 <code>LD_PRELOAD</code> 技巧，在系统上的几乎任何程序中启用垃圾收集。如果您怀疑某个程序正在泄漏内存，那么您可以使用这个垃圾收集器来控制进程。在早期，当 Mozilla 严重地泄漏内存时，很多人在其中使用了这项技术。这种垃圾收集器既可以在 Windows&#174; 下运行，也可以在 UNIX 下运行。 </p>
<p>垃圾收集的一些优点：
<ul>
    <li>您永远不必担心内存的双重释放或者对象的生命周期。
    <li>使用某些收集器，您可以使用与常规分配相同的 API。 </li>
</ul>
<p>&nbsp;</p>
<p>其缺点包括：
<ul>
    <li>使用大部分收集器时，您都无法干涉何时释放内存。
    <li>在多数情况下，垃圾收集比其他形式的内存管理更慢。
    <li>垃圾收集错误引发的缺陷难于调试。
    <li>如果您忘记将不再使用的指针设置为 null，那么仍然会有内存泄漏。 </li>
</ul>
<p>&nbsp;</p>
<br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
        </tr>
    </tbody>
</table>
<table class=no-print cellSpacing=0 cellPadding=0 align=right>
    <tbody>
        <tr align=right>
            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
            <table cellSpacing=0 cellPadding=0 border=0>
                <tbody>
                    <tr>
                        <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                        <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/l-memory/#main"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name=N1042A><span class=atitle>结束语</span></a></p>
<p>一切都需要折衷：性能、易用、易于实现、支持线程的能力等，这里只列出了其中的一些。为了满足项目的要求，有很多内存管理模式可以供您使用。每种模式都有大量的实现，各有其优缺点。对很多项目来说，使用编程环境默认的技术就足够了，不过，当您的项目有特殊的需要时，了解可用的选择将会有帮助。下表对比了本文中涉及的内存管理策略。 </p>
<p><a name=N10434><span class=smalltitle>表 1. 内存分配策略的对比</span></a></p>
<p>
<table cellSpacing=1 cellPadding=3 width="60%" border=1>
    <tbody>
        <tr vAlign=top>
            <td><strong>策略</strong> </td>
            <td><strong>分配速度</strong> </td>
            <td><strong>回收速度</strong> </td>
            <td><strong>局部缓存</strong> </td>
            <td><strong>易用性</strong> </td>
            <td><strong>通用性</strong> </td>
            <td><strong>实时可用</strong> </td>
            <td><strong>SMP 线程友好</strong> </td>
        </tr>
        <tr>
            <td>定制分配程序 </td>
            <td>取决于实现 </td>
            <td>取决于实现 </td>
            <td>取决于实现 </td>
            <td>很难 </td>
            <td>无 </td>
            <td>取决于实现 </td>
            <td>取决于实现 </td>
        </tr>
        <tr>
            <td>简单分配程序</td>
            <td>内存使用少时较快</td>
            <td>很快</td>
            <td>差 </td>
            <td>容易 </td>
            <td>高 </td>
            <td>否 </td>
            <td>否 </td>
        </tr>
        <tr>
            <td>GNU <code>malloc</code> </td>
            <td>中 </td>
            <td>快 </td>
            <td>中 </td>
            <td>容易 </td>
            <td>高 </td>
            <td>否 </td>
            <td>中</td>
        </tr>
        <tr>
            <td>Hoard </td>
            <td>中 </td>
            <td>中 </td>
            <td>中 </td>
            <td>容易 </td>
            <td>高 </td>
            <td>否 </td>
            <td>是 </td>
        </tr>
        <tr>
            <td>引用计数 </td>
            <td>N/A </td>
            <td>N/A </td>
            <td>非常好 </td>
            <td>中 </td>
            <td>中 </td>
            <td>是（取决于 <code>malloc</code> 实现） </td>
            <td>取决于实现 </td>
        </tr>
        <tr>
            <td>池 </td>
            <td>中 </td>
            <td>非常快 </td>
            <td>极好 </td>
            <td>中 </td>
            <td>中 </td>
            <td>是（取决于 <code>malloc</code> 实现） </td>
            <td>取决于实现 </td>
        </tr>
        <tr>
            <td>垃圾收集 </td>
            <td>中（进行收集时慢） </td>
            <td>中 </td>
            <td>差 </td>
            <td>中 </td>
            <td>中 </td>
            <td>否 </td>
            <td>几乎不 </td>
        </tr>
        <tr>
            <td>增量垃圾收集 </td>
            <td>中 </td>
            <td>中 </td>
            <td>中 </td>
            <td>中 </td>
            <td>中 </td>
            <td>否 </td>
            <td>几乎不 </td>
        </tr>
        <tr>
            <td>增量保守垃圾收集 </td>
            <td>中 </td>
            <td>中 </td>
            <td>中 </td>
            <td>容易 </td>
            <td>高 </td>
            <td>否 </td>
            <td>几乎不</td>
        </tr>
    </tbody>
</table>
</p>
<br><br>
<p><a name=resources><span class=atitle>参考资料 </span></a></p>
<ul>
    <li>您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/linux/library/l-memory/?S_TACT=105AGX52&amp;S_CMP=cn-a-l" target=_blank>英文原文</a>。 <br></li>
</ul>
<p><strong>Web 上的文档</strong>
<ul>
    <li><a href="http://www.gnu.org/software/libc/manual/html_node/Obstacks.html#Obstacks">GNU C Library 手册的 obstacks 部分</a> 提供了 obstacks 编程接口。 <br><br>
    <li><a href="http://apr.apache.org/docs/apr/group__apr__pools.html">Apache Portable Runtime 文档</a> 描述了它们的池式分配程序的接口。 <br></li>
</ul>
<strong>基本的分配程序</strong>
<ul>
    <li><a href="http://gee.cs.oswego.edu/dl/html/malloc.html">Doug Lea 的 Malloc</a> 是最流行的内存分配程序之一。 <br><br>
    <li><a href="http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/libc/stdlib/malloc.c">BSD Malloc</a> 用于大部分基于 BSD 的系统中。 <br><br>
    <li><a href="http://www.malloc.de/en/">ptmalloc</a> 起源于 Doug Lea 的 malloc，用于 GLIBC 之中。 <br><br>
    <li><a href="http://www.cs.umass.edu/~emery/hoard/">Hoard</a> 是一个为多线程应用程序优化的 <code>malloc</code> 实现。 <br><br>
    <li><a href="http://ftp.gnu.org/gnu/gdb/gdb-6.2.tar.gz">GNU Memory-Mapped Malloc（GDB 的组成部分）</a> 是一个基于 <code>mmap()</code> 的 <code>malloc</code> 实现。 <br></li>
</ul>
<strong>池式分配程序</strong>
<ul>
    <li><a href="http://www.gnu.org/software/libc/">GNU Obstacks</a>（GNU Libc 的组成部分）是安装最多的池式分配程序，因为在每一个基于 glibc 的系统中都有它。 <br><br>
    <li><a href="http://apr.apache.org/">Apache 的池式分配程序（Apache Portable Runtime 中）</a> 是应用最为广泛的池式分配程序。 <br><br>
    <li><a href="ftp://ftp.vistech.net/pub/squid/squid-2/STABLE/">Squid</a> 有其自己的池式分配程序。 <br><br>
    <li><a href="http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/kern/subr_pool.c">NetBSD</a> 也有其自己的池式分配程序。 <br><br>
    <li><a href="http://www.samba.org/samba/ftp/samba-latest.tar.gz">talloc</a> 是一个池式分配程序，是 Samba 的组成部分。 <br></li>
</ul>
<strong>智能指针和定制分配程序</strong>
<ul>
    <li><a href="http://sourceforge.net/projects/loki-lib/">Loki C++ Library</a> 有很多为 C++ 实现的通用模式，包括智能指针和一个定制的小对象分配程序。 <br></li>
</ul>
<strong>垃圾收集器</strong>
<ul>
    <li><a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/">Hahns Boehm Conservative Garbage Collector</a> 是最流行的开源垃圾收集器，它可以用于常规的 C/C++ 程序。 <br></li>
</ul>
<strong>关于现代操作系统中的虚拟内存的文章</strong>
<ul>
    <li>Marshall Kirk McKusick 和 Michael J. Karels 合著的 <a href="http://docs.freebsd.org/44doc/papers/newvm.html">A New Virtual Memory Implementation for Berkeley UNIX</a> 讨论了 BSD 的 VM 系统。 <br><br>
    <li><a href="http://www.skynet.ie/~mel/projects/vm/">Mel Gorman's Linux VM Documentation</a> 讨论了 Linux VM 系统。 <br></li>
</ul>
<strong>关于 malloc 的文章</strong>
<ul>
    <li>Poul-Henning Kamp 撰写的 <a href="http://docs.freebsd.org/44doc/papers/malloc.html">Malloc in Modern Virtual Memory Environments</a> 讨论的是 <code>malloc</code> 以及它如何与 BSD 虚拟内存交互。 <br><br>
    <li>Berger、McKinley、Blumofe 和 Wilson 合著的 <a href="ftp://ftp.cs.utexas.edu/pub/emery/papers/asplos2000.pdf">Hoard -- a Scalable Memory Allocator for Multithreaded Environments</a> 讨论了 Hoard 分配程序的实现。 <br><br>
    <li>Marshall Kirk McKusick 和 Michael J. Karels 合著的 <a href="http://docs.freebsd.org/44doc/papers/kernmalloc.html">Design of a General Purpose Memory Allocator for the 4.3BSD UNIX Kernel</a> 讨论了内核级的分配程序。 <br><br>
    <li>Doug Lea 撰写的 <a href="http://gee.cs.oswego.edu/dl/html/malloc.html">A Memory Allocator</a> 给出了一个关于设计和实现分配程序的概述，其中包括设计选择与折衷。 <br><br>
    <li>Emery D. Berger 撰写的 <a href="http://www.cs.utexas.edu/ftp/pub/techreports/tr02-52.pdf">Memory Management for High-Performance Applications</a> 讨论的是定制内存管理以及它如何影响高性能应用程序。 <br></li>
</ul>
<strong>关于定制分配程序的文章</strong>
<ul>
    <li>Doug Lea 撰写的 <a href="ftp://g.oswego.edu/pub/papers/C++Report89.txt">Some Storage Management Techniques for Container Classes</a> 描述的是为 C++ 类编写定制分配程序。 <br><br>
    <li>Berger、Zorn 和 McKinley 合著的 <a href="ftp://ftp.cs.utexas.edu/pub/emery/papers/pldi2001.pdf">Composing High-Performance Memory Allocators</a> 讨论了如何编写定制分配程序来加快具体工作的速度。 <br><br>
    <li>Berger、Zorn 和 McKinley 合著的 <a href="ftp://ftp.cs.utexas.edu/pub/emery/papers/reconsidering-custom.pdf">Reconsidering Custom Memory Allocation</a> 再次提及了定制分配的主题，看是否真正值得为其费心。 <br></li>
</ul>
<strong>关于垃圾收集的文章</strong>
<ul>
    <li>Paul R. Wilson 撰写的 <a href="ftp://ftp.cs.utexas.edu/pub/garbage/bigsurv.ps">Uniprocessor Garbage Collection Techniques</a> 给出了垃圾收集的一个基本概述。 <br><br>
    <li>Benjamin Zorn 撰写的 <a href="ftp://ftp.cs.colorado.edu/pub/techreports/zorn/CU-CS-573-92.ps.Z">The Measured Cost of Garbage Collection</a> 给出了关于垃圾收集和性能的硬数据（hard data）。 <br><br>
    <li>Hans-Juergen Boehm 撰写的 <a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/myths.ps">Memory Allocation Myths and Half-Truths</a> 给出了关于垃圾收集的神话（myths）。 <br><br>
    <li>Hans-Juergen Boehm 撰写的 <a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/papers/pldi93.ps.Z">Space Efficient Conservative Garbage Collection</a> 是一篇描述他的用于 C/C++ 的垃圾收集器的文章。 <br></li>
</ul>
<strong>Web 上的通用参考资料</strong>
<ul>
    <li><a href="http://www.memorymanagement.org/">内存管理参考</a> 中有很多关于内存管理参考资料和技术文章的链接。 <br><br>
    <li><a href="http://www.cs.utexas.edu/users/oops/papers.html">关于内存管理和内存层级的 OOPS Group Papers</a> 是非常好的一组关于此主题的技术文章。 <br><br>
    <li><a href="http://www.cantrip.org/wave12.html">C++ 中的内存管理</a>讨论的是为 C++ 编写定制的分配程序。 <br><br>
    <li><a href="http://www.conman.org/projects/essays/memmgr.html">Programming Alternatives: Memory Management</a> 讨论了程序员进行内存管理时的一些选择。 <br><br>
    <li><a href="http://www.iecc.com/gclist/GC-faq.html">垃圾收集 FAQ</a> 讨论了关于垃圾收集您需要了解的所有内容。 <br><br>
    <li><a href="http://www.cs.ukc.ac.uk/people/staff/rej/gcbib/gcbibG.html">Richard Jones 的 Garbage Collection Bibliography</a> 有指向任何您想要的关于垃圾收集的文章的链接。 <br></li>
</ul>
<strong>书籍</strong>
<ul>
    <li>Michael Daconta 撰写的 <a href="http://www.amazon.com/exec/obidos/ASIN/0471049980/freeeducation-20/"><em>C++ Pointers and Dynamic Memory Management</em> </a>介绍了关于内存管理的很多技术。 <br><br>
    <li>Frantisek Franek 撰写的 <a href="http://devworks.krcinfo.com/WebForms/ProductDetails.aspx?ProductID=0521520436"><em>Memory as a Programming Concept in C and C++</em> </a>讨论了有效使用内存的技术与工具，并给出了在计算机编程中应当引起注意的内存相关错误的角色。 <br><br>
    <li>Richard Jones 和 Rafael Lins 合著的 <a href="http://devworks.krcinfo.com/WebForms/ProductDetails.aspx?ProductID=0471941484"><em>Garbage Collection: Algorithms for Automatic Dynamic Memory Management</em> </a>描述了当前使用的最常见的垃圾收集算法。 <br><br>
    <li>在 Donald Knuth 撰写的 <em>The Art of Computer Programming</em> 第 1 卷 <a href="http://devworks.krcinfo.com/WebForms/ProductDetails.aspx?ProductID=0201896834"><em>Fundamental Algorithms</em> </a>的第 2.5 节&#8220;Dynamic Storage Allocation&#8221;中，描述了实现基本的分配程序的一些技术。 <br><br>
    <li>在 Donald Knuth 撰写的 <em>The Art of Computer Programming</em> 第 1 卷 <a href="http://devworks.krcinfo.com/WebForms/ProductDetails.aspx?ProductID=0201896834"><em>Fundamental Algorithms</em> </a>的第 2.3.5 节&#8220;Lists and Garbage Collection&#8221;中，讨论了用于列表的垃圾收集算法。 <br><br>
    <li>Andrei Alexandrescu 撰写的 <a href="http://devworks.krcinfo.com/WebForms/ProductDetails.aspx?ProductID=0201704315"><em>Modern C++ Design</em> </a>第 4 章&#8220;Small Object Allocation&#8221;描述了一个比 C++ 标准分配程序效率高得多的一个高速小对象分配程序。 <br><br>
    <li>Andrei Alexandrescu 撰写的 <a href="http://devworks.krcinfo.com/WebForms/ProductDetails.aspx?ProductID=0201704315"><em>Modern C++ Design</em> </a>第 7 章&#8220;Smart Pointers&#8221;描述了在 C++ 中智能指针的实现。 <br><br>
    <li>Jonathan 撰写的 <a href="http://www.amazon.com/exec/obidos/ASIN/0975283847/freeeducation-20/"><em>Programming from the Ground Up</em> </a>第 8 章&#8220;Intermediate Memory Topics&#8221;中有本文使用的简单分配程序的一个汇编语言版本。 <br></li>
</ul>
<strong>来自 developerWorks</strong>
<ul>
    <li><a href="http://www.ibm.com/developerworks/cn/linux/wa-memmng/">自我管理数据缓冲区内存</a> （developerWorks，2004 年 1 月）略述了一个用于管理内存的自管理的抽象数据缓存器的伪 C （pseudo-C）实现。 <br><br>
    <li><a href="http://www.ibm.com/developerworks/eserver/articles/framework.html?S_TACT=105AGX52&amp;S_CMP=cn-a-l">A framework for the user defined malloc replacement feature</a> （developerWorks，2002 年 2 月）展示了如何利用 AIX 中的一个工具，使用自己设计的内存子系统取代原有的内存子系统。 <br><br>
    <li><a href="http://www.ibm.com/developerworks/cn/linux/sdk/l-debug/index.html">掌握 Linux 调试技术</a> （developerWorks，2002 年 8 月）描述了可以使用调试方法的 4 种不同情形：段错误、内存溢出、内存泄漏和挂起。 <br><br>
    <li>在 <a href="http://www.ibm.com/developerworks/cn/java/j-leaks/index.html">处理 Java 程序中的内存漏洞</a> （developerWorks，2001 年 2 月）中，了解导致 Java 内存泄漏的原因，以及何时需要考虑它们。 <br><br>
    <li>在 <a href="http://www.ibm.com/developerworks/cn/linux/">developerWorks Linux 专区</a>中，可以找到更多为 Linux 开发人员准备的参考资料。 <br><br>
    <li>从 developerWorks 的 <a href="http://www.ibm.com/developerworks/cn/linux/linux-speed-start/">Speed-start your Linux app</a> 专区中，可以下载运行于 Linux 之上的 IBM 中间件产品的免费测试版本，其中包括 WebSphere&#174; Studio Application Developer、WebSphere Application Server、DB2&#174; Universal Database、Tivoli&#174; Access Manager 和 Tivoli Directory Server，查找 how-to 文章和技术支持。 <br><br>
    <li>通过参与 <a href="http://www.ibm.com/developerworks/blogs/?S_TACT=105AGX52&amp;S_CMP=cn-a-l">developerWorks blogs</a> 加入到 developerWorks 社区。 <br><br>
    <li>可以在 Developer Bookstore Linux 专栏中定购 <a href="http://devworks.krcinfo.com/WebForms/ProductList.aspx?Search=Category&amp;id=300&amp;parent=Linux" target=new>打折出售的 Linux 书籍</a>。 <br></li>
</ul>
<br><br>
<p><a name=author><span class=atitle>关于作者</span></a></p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td colSpan=3><img height=5 alt="" src="http://www.ibm.com/i/c.gif" width="100%"></td>
        </tr>
        <tr vAlign=top align=left>
            <td>
            <p>&nbsp;</p>
            </td>
            <td><img height=5 alt="" src="http://www.ibm.com/i/c.gif" width=4></td>
            <td width="100%">
            <p>Jonathan Bartlett 是 <a href="http://www.cafeshops.com/bartlettpublish.8640017"><em>Programming from the Ground Up</em> </a>一书的作者，这本书介绍的是 Linux 汇编语言编程。Jonathan Bartlett 是 New Media Worx 的总开发师，负责为客户开发 Web、视频、kiosk 和桌面应用程序。您可以通过 <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#106;&#111;&#104;&#110;&#110;&#121;&#98;&#64;&#101;&#115;&#107;&#105;&#109;&#111;&#46;&#99;&#111;&#109;&#63;&#99;&#99;&#61;">johnnyb@eskimo.com</a> 与 Jonathan 联系。 </p>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/xixidabao/aggbug/108120.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2007-04-03 09:33 <a href="http://www.blogjava.net/xixidabao/archive/2007/04/03/108120.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>BiJiao.java</title><link>http://www.blogjava.net/xixidabao/archive/2006/10/15/75198.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Sat, 14 Oct 2006 16:15:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2006/10/15/75198.html</guid><description><![CDATA[public class BiJiao<br />{<br />   boolean comp(Object a,Object b)<br />   {<br />     return a==b;<br />    }<br />    <br />    boolean comp1(Object a,Object b)<br />    {<br />     return a.equals(b);<br />    }<br />    <br />    boolean compInt(int i,int j)<br />    {<br />     return i==j;<br />    }<br />    <br />    boolean compInt1(int i,int j)<br />    {<br />     return (Integer.valueOf(i)).equals(Integer.valueOf(j));<br />    }<br />    <br />    public void biObject(Object a,Object b)<br />    {<br />     if(comp(a,b))<br />     System.out.println("用\"==\"比较的结果：       "+"true");<br />     else<br />     System.out.println("用\"==\"比较的结果：       "+"false");<br />     if(comp1(a,b))<br />     System.out.println("用\"equals()\"比较的结果： "+"true");<br />     else<br />     System.out.println("用\"equals()\"比较的结果： "+"flase");<br />    }<br />    <br />    public void biInt(int i,int j)<br />    {<br />     if(compInt(i,j))<br />     System.out.println("用\"==\"比较的结果：       "+"true");<br />     else<br />     System.out.println("用\"==\"比较的结果：       "+"false");<br />     if(compInt1(i,j))<br />     System.out.println("用\"equals()\"比较的结果： "+"true");<br />     else<br />     System.out.println("用\"equals()\"比较的结果： "+"flase");<br />    }<br />     <br />    public int test(String t)<br />       {<br />        int k=0;<br />         String str="0123456789";<br />        for(int i=0;i&lt;t.length();i++)<br />       {<br />        char ch1=(char)t.charAt(i);<br />        <br />        if(str.indexOf(ch1)==-1)<br />          k++;<br />       }<br />       return k;<br />     }<br />     <br />    public static void main(String[] args)<br />    {<br />      BiJiao biJiao=new BiJiao();<br />      <br />      if(args.length&lt;2)<br />      {<br />        <br />        System.out.println("请输入两个字符或数字：");<br />        System.exit(0);<br />       }<br />       <br />       String a=args[0];<br />       String b=args[1];<br />       <br />       int k=biJiao.test(a);<br />       int p=biJiao.test(b);<br />      <br />       <br />       if(k==0&amp;&amp;p==0)<br />       {<br />        System.out.println("您输入的是数字：       "+a+" 和 "+b);<br />        int i=Integer.parseInt(a);<br />         int j=Integer.parseInt(b);<br />        biJiao.biInt(i,j);<br />       }<br />       else<br />         {<br />          System.out.println("您输入的是字符：     "+a+" 和 "+b);<br />          biJiao.biObject(a,b);<br />         }<br />    }<br />}<br />       <img src ="http://www.blogjava.net/xixidabao/aggbug/75198.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2006-10-15 00:15 <a href="http://www.blogjava.net/xixidabao/archive/2006/10/15/75198.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java的垃圾回收（Garbage Collection）机制 </title><link>http://www.blogjava.net/xixidabao/archive/2006/09/15/69776.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Thu, 14 Sep 2006 16:56:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2006/09/15/69776.html</guid><description><![CDATA[
		<table cellspacing="0" cellpadding="0" align="left" border="0">
				<tbody>
						<tr>
								<td>
										<span id="leftAD">
												<div id="BannerZoneAD_Div11" style="Z-INDEX: 1; VISIBILITY: visible; WIDTH: 360px; HEIGHT: 300px">
														<object id="AD_11" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" height="300" width="360" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" name="AD_11">
																<param name="_cx" value="9525" />
																<param name="_cy" value="7938" />
																<param name="FlashVars" value="" />
																<param name="Movie" value="http://www.chinaitlab.com/cms/images/ad/360-300green.swf" />
																<param name="Src" value="http://www.chinaitlab.com/cms/images/ad/360-300green.swf" />
																<param name="WMode" value="Window" />
																<param name="Play" value="-1" />
																<param name="Loop" value="-1" />
																<param name="Quality" value="AutoHigh" />
																<param name="SAlign" value="" />
																<param name="Menu" value="-1" />
																<param name="Base" value="" />
																<param name="AllowScriptAccess" value="" />
																<param name="Scale" value="ShowAll" />
																<param name="DeviceFont" value="0" />
																<param name="EmbedMovie" value="0" />
																<param name="BGColor" value="" />
																<param name="SWRemote" value="" />
																<param name="MovieData" value="" />
																<param name="SeamlessTabbing" value="1" />
																<param name="Profile" value="0" />
																<param name="ProfileAddress" value="" />
																<param name="ProfilePort" value="0" />
																<embed name="AD_11" id="AD_11" width="360" height="300" src="http://www.chinaitlab.com/cms/images/ad/360-300green.swf" quality="autohigh" pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash">
																</embed>
														</object>
												</div>
												<script src="/adjs/ADCount.asp?Action=View&amp;ADID=11">
												</script>
										</span>
								</td>
						</tr>
				</tbody>
		</table>
		<p>
				<strong>    一。谁在做Garbage Collection？</strong>
		</p>
		<p>    一种流行的说法：在C++里，是系统在做垃圾回收；而在Java里，是Java自身在做。</p>
		<p>    在C++里，释放内存是手动处理的，要用delete运算符来释放分配的内存。这是流行的说法。确切地说，是应用认为不需要某实体时，就需用delete告诉系统，可以回收这块空间了。这个要求，对编码者来说，是件很麻烦、很难做到的事。随便上哪个BBS，在C/C++版块里总是有一大堆关于内存泄漏的话题。</p>
		<p>    Java采用一种不同的，很方便的方法：Garbage Collection.垃圾回收机制放在JVM里。JVM完全负责垃圾回收事宜，应用只在需要时申请空间，而在抛弃对象时不必关心空间回收问题。</p>
		<p>
				<strong>    二。对象在啥时被丢弃？</strong>
		</p>
		<p>    在C++里，当对象离开其作用域时，该对象即被应用抛弃。</p>
		<p>    是对象的生命期不再与其作用域有关，而仅仅与引用有关。</p>
		<p>    Java的垃圾回收机制一般包含近十种算法。对这些算法中的多数，我们不必予以关心。只有其中最简单的一个：引用计数法，与编码有关。</p>
		<p>    一个对象，可以有一个或多个引用变量指向它。当一个对象不再有任何一个引用变量指向它时，这个对象就被应用抛弃了。或者说，这个对象可以被垃圾回收机制回收了。</p>
		<p>    这就是说，当不存在对某对象的任何引用时，就意味着，应用告诉JVM：我不要这个对象，你可以回收了。</p>
		<p>    JVM的垃圾回收机制对堆空间做实时检测。当发现某对象的引用计数为0时，就将该对象列入待回收列表中。但是，并不是马上予以销毁。</p>
		<p> <strong>   三。丢弃就被回收？</strong></p>
		<p>    该对象被认定为没有存在的必要了，那么它所占用的内存就可以被释放。被回收的内存可以用于后续的再分配。</p>
		<p>    