随笔-204  评论-90  文章-8  trackbacks-0
 


这是一些在工作中常用到的一些小技术,拿出来和大家分享

1.用:set list来查看所有不可见字符,反之用:set nolist关闭
2.vim操作ftp,打开:
:e ftp://192.168.0.1/1.txt
保存(如果不存在则创建):
:w ftp://192.168.0.1/1.txt
读取:
:r ftp://192.168.0.1/1.txt
以上操作第一次打开时需要输入用户名和密码,
以后就不用了,vim 会记住的。
3.Ctrl+R 是在编辑时或者命令行界面下调入寄存器值的热键,Ctrl+R+/ 会得到上一次查询的条件,Ctrl+R+<寄存器名>; 相当于 Normal 模式下的 "<寄存器名>;p 命令
4.vim在编辑一个文件时如果打开多个文件,:args <CTRL-R>;% file2 file3
5.如何删除连续两行之间的回车符,使连续的两行成为一行,Jx
6.想显示行号,可以用 :set nu
7.vim中光标在C函数和系统调用上时,按K进入man手册页
8.V 打开"可视模式"(不是虚拟模式,虚拟是 virtual)后,可以有很多种办法移动光标的,不一定非得用 h j k l , 比如可以搜索定位, 也可以用 [[ ]] ][ [] } { 等段落定位的命令. v]] v[[ v} 这样就可以选中一大块,而不用一行一行地选 还有 H L 这些都可以用. 详细请 help motion 另外, vim 内置了很多以 a 打头的文本对象, 如 a{ 表示一个 {} 块, ap 表示一个段落等等。=a{ 就可以重排当前语法块.
9.全选的命令是 ggVG gg表示到第一行第一个字母, V进入visual line G则到文件尾。
10.vim是否支持将语法高亮度显示的结果保存为一个html文档,:TOhtml
11.用:split new | r!ls 来获得外部命令的输入,其中r !ls 则表示执行外部命令 ls,并且捕获(读入)它的输出。
12.vi中用``就可以回到刚才的位置,vim中用ctrl+o
13.用:set ai的命令来启动自动缩进。用:syntax on命令来启动语法着色
14.在"插入模式"下删除光标到行尾的字符,^od$,^o 表示同时按住 Ctrl 和 O 键,其实也可以是^oD,还有就是如果要删除到某个字符位置的话,就用^odfx,x表示要删除到的字符
15.自动缩进set autoindent 和set cindent
16.括号自动补全:iab ( ()
17.删除所有偶数行<ESC>;ggqajddq10000@a
18.排版代码gg=G
19.:args查看正在编辑的文件名或者用ctrl+g
20.gj gk 分别可以向下、向上移动一个物理行
posted @ 2008-07-16 16:35 一凡 阅读(729) | 评论 (0)编辑 收藏
这部分简要介绍一下TCP/IP的内部结构,为讨论与互联网有关的安全问题打下基础。TCP/IP协议组之所以流行,部分原因是因为它可以用在各 种各样的信道和底层协议(例如T1和X.25、以太网以及RS-232串行接口)之上。确切地说,TCP/IP协议是一组包括TCP协议和IP协议, UDP(User Datagram Protocol)协议、ICMP(Internet Control Message Protocol)协议和其他一些协议的协议组。

TCP/IP协议的开发研制人员将Internet分为五个层次,以便于理解,它也称为互联网分层模型或互联网分层参考模型,如下表:

应用层(第五层)
传输层(第四层)
互联网层(第三层)
网络接口层(第二层)
物理层(第一层)

物理层:对应于网络的基本硬件,这也是Internet物理构成,即我们可以看得见的硬设备,如PC机、互连网服务器、网络设备等,必须对这些硬设备的电气特性作一个规范,使这些设备都能够互相连接并兼容使用。

网络接口层:它定义了将资料组成正确帧的规程和在网络中传输帧的规程,帧是指一串资料,它是资料在网络中传输的单位。

互联网层:本层定义了互联网中传输的“信息包”格式,以及从一个用户通过一个或多个路由器到最终目标的"信息包"转发机制。
传输层:为两个用户进程之间建立、管理和拆除可靠而又有效的端到端连接。

应用层:它定义了应用程序使用互联网的规程。

详细请看

参考资料:http://baike.baidu.com/view/7649.htm
posted @ 2008-07-16 11:38 一凡 阅读(186) | 评论 (0)编辑 收藏


任务调度的crond常驻命令
crond
linux用来定期执行程序的命令。当安装完成操作系统之后,默认便会启动此任务调度命令。crond命令每分锺会定期检查是否有要执行的工作,如果有要执行的工作便会自动执行该工作。而linux任务调度的工作主要分为以下两类:
1
、系统执行的工作:系统周期性所要执行的工作,如备份系统数据、清理缓存
2
、个人执行的工作:某个用户定期要做的工作,例如每隔10分钟检查邮件服务器是否有新信,这些工作可由每个用户自行设置

 

CrontabUNIX系统下的定时任务触发器,其使用者的权限记载在下列两个文件中:

 

文件

 

含义

 

/etc/cron.deny

 

该文件中所列的用户不允许使用Crontab命令

 

/etc/cron.allow

 

该文件中所列的用户允许使用Crontab命令

 

/var/spool/cron/

 

是所有用户的crontab文件

 

/var/spool/cron/crontabs

/var/spool/cron/crontabs


Crontab
命令的格式为:crontab –l|-r|-e|-i [username],其参数含义如表一:

 

参数名称

 

含义

 

示例

 

-l

 

显示用户的Crontab文件的内容

 

crontabl –l

 

-i

 

删除用户的Crontab文件前给提示

 

crontabl -ri

 

-r

 

Crontab目录中删除用户的Crontab文件

 

crontabl -r

 

-e

 

编辑用户的Crontab文件

 

crontabl -e

 


用户所建立的Crontab文件存于/var/spool/cron中,其文件名与用户名一致。
它的格式共分为六段,前五段为时间设定段,第六段为所要执行的命令段,
格式如下:* * * * * <command>
其时间段的含义如表二:

 

 

含义

 

取值范围

 

第一段

 

代表分钟

 

0—59

 

第二段

 

代表小时

 

0—23

 

第三段

 

代表日期

 

1—31

 

第四段

 

代表月份

 

1—12

 

第五段

 

代表星期几,0代表星期日

 

0—6

 

例:如果用户的Crontab文件的内容是:29 19 * * * echo its dinner time,则系统每天的19:29显示‘its dinner time’

示例(创建一个cron全过程,每分钟都会在test.txt里输入当前时间):

 

1.     以普通用户登录linux系统(我用的是CentOS4.1)

 

2.     $crontab –e
说明:系统默认的编辑器是VIM,如果不是请加上以下shell:
    $EDITOR=vi
    $export EDITOR

 

3.     输入”*/1 * * * * date >> $HOME/test.txt”,save and exit VIM

 

4.     $su root

 

5.     $cd /etc/init.d

 

6.     ./crond restart

 

下面看看看几个具体的例子:
0 */2 * * * /sbin/service httpd restart 
意思是每两个小时重启一次apache

 

● 50 7 * * * /sbin/service sshd start  意思是每天750开启ssh服务

 

● 50 22 * * * /sbin/service sshd stop  意思是每天2250关闭ssh服务

 

● 0 0 1,15 * * fsck /home  每月1号和15号检查/home 磁盘

 

● 1 * * * * /home/bruce/backup  每小时的第一分执行 /home/bruce/backup这个文件

 

● 00 03 * * 1-5 find /home "*.xxx" -mtime +4 -exec rm {} \;  每周一至周五3点钟,在目录/home中,查找文件名为*.xxx的文件,并删除4天前的文件。
● 30 6 */10 * * ls  意思是每月的1、11、21、31日是的6:30执行一次ls命令
posted @ 2008-06-30 11:57 一凡 阅读(264) | 评论 (0)编辑 收藏
 命令如下:
$RESIN_HOME/bin/httpd.sh -conf $RESIN_HOME/conf/resin.conf -Djava.awt.headless=true -server 'servername' -pid 'log/coinstat.pid' -verbose start


posted @ 2008-06-20 16:03 一凡 阅读(413) | 评论 (0)编辑 收藏
1.命令行参数(Command-line arguments)

-install (Windows) install Resin as a service (but doesn't automatically start.)

-install-as xxx (Windows) install Resin as a named service (but doesn't utomatically start.)

-remove (Windows) install Resin as a service (but doesn't automatically start.)

-remove-as xxx (Windows) remove Resin as a named service (but doesn't automatically start.)

2.JDK参数(JDK arguments:在Httpd.sh参数的配置)
<1>.文件位置:${resin30}/bin/httpd.sh

<2>.args='-J-server -Xms200m -Xmx1024m -Xloggc:./log/gc.log -XX:MaxNewSize=256m -XX:MaxPermSize=256m -Djava.awt.headless=true'
参数说明:

(1)J-server -Xms200m -Xmx1024m 其中,-Xms200m 表示启动时,初时内存大小,-Xmx1024m最大内存占用大小。(-Xmn100m可选)

(2)-XX:MaxNewSize=256m -XX:MaxPermSize=256m 表示:内存的永久保存区域(PermGen space)的大小,PermGen space的全称是Permanent Generation space,是指内存的永久保存区域OutOfMemoryError: PermGen space从表面上看就是内存溢出,解决方法也一定是加大内存。说说为什么会内存益出:这一部分用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理
一般 -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m这些值不需要设置的,除非perm溢出,设置一下MaxPermSize就行,启动脚本加上-server后,也不用在设置MaxNewSize。

(3)-Djava.awt.headless=true 解决在linux/unix验证码图片不能显示的问题。

3.通用 JVM 参数

指定传递到启动应用程序服务器进程的 Java 虚拟机代码的命令行参数。

下面是可以在“通用 JVM 参数”字段中输入的可选命令行参数。如果输入多个自变量,请在每个自变量之间输入空格。
重要: 如果该参数表明它仅适用于 IBM Developer Kit,您就无法为另一个 JVM 使用该参数,例如 Sun JDK 或 HP JDK。
-Xquickstart
可以使用 -Xquickstart 来以低于缺省方式的优化级别进行初始编译。之后,根据采样结果的不同,可以采用缺省方式下初始编译的级别来进行重新编译。适合于早期的平均速度比长期运行吞吐量更为重要的应用程序 -Xquickstart。在某些调试方案、测试装置和短时间运行的工具中,可以将启动时间缩短 15% 到 20%。

-Xverify:none
如果在类装入期间要跳过类验证阶段,可以使用 -Xverify:none。在启用即时(JIT)编译器的情况下使用 -Xverify:none 能够将启动时间缩短 10-15%。

-Xnoclassgc
可以使用 -Xnoclassgc 来禁用类垃圾回收。此操作可以提高类重用程度,并可以略微提高性能。但是,其代价是您无法收集这些类拥有的资源。可以使用 verbose:gc 配置设置(此设置将输出类垃圾回收统计信息)来监控垃圾回收。检查这些统计信息将帮助您理解再生的资源和再生资源必需的垃圾回收量之间的平衡。然而,如果在您的工作负载中反复地垃圾回收同一组类,那么您应该禁用垃圾回收。缺省情况下,启用类垃圾回收。

-Xgcthreads
可以同时使用数个垃圾回收线程,这也称为并行垃圾回收。在“通用 JVM 参数”字段中输入此值时,还要输入您的机器的处理器数,例如,-Xgcthreadsn,其中 n 是处理器数。在具有 n 个处理器的节点上,缺省线程数是 n。如果您的机器有多个处理器,那么您应该使用并行垃圾回收。此参数仅对于 IBM Developer Kit 是有效的。

-Xnocompactgc
可以使用 -Xnocompactgc 来禁用堆压缩,这是成本最高的垃圾回收操作。在 IBM Developer Kit 中避免压缩。如果您禁用堆压缩,那么消除了所有相关的开销。

-Xinitsh
可以使用 -Xinitsh 来设置存储类对象的堆的初始大小。方法定义和静态字段也与类对象一起存储。尽管系统堆大小没有上限,但是设置初始大小,以避免产生涉及调用操作系统内存管理器的扩展系统堆大小的花销。您可以通过了解 WebSphere Application Server 产品中装入的类数目(大约是 8,000 个类)以及它们的平均大小,来计算理想的初始系统堆大小。了解应用程序可帮助您将它们计算进去。您只可以为 IBM Developer Kit 使用此参数。

-Xgpolicy
可以使用 -Xgpolicy 来设置垃圾回收策略。如果垃圾回收策略(gcpolicy)设置为 optavgpause,使用并发作标记跟踪在堆满之前从堆栈启动的应用程序线程。垃圾回收器暂停变得协调统一了,并且长时间的暂停也不再明显了。其代价是吞吐量降低,这是因为线程可能必须要执行额外的操作。缺省的建议值为 optthruput。输入值 -Xgcpolicy:[optthruput|optavgpause]。您只可以为 IBM Developer Kit 使用此参数。

-XX
基于 Sun 的 Java Development Kit(JDK)V1.4.2 有生成垃圾回收功能,这允许分隔内存池以包含不同时效的对象。垃圾回收循环根据时效收集与其他对象彼此独立的对象。使用其他参数,您可以单独设置内存池的大小。为了实现更好的性能,您应该对包含短期存活对象的池的大小进行设置,以使该池中的对象的存活时间不会超过一个垃圾回收循环。新生成的池的大小由 NewSize 和 MaxNewSiz 参数确定。

第一次垃圾回收循环中存活下来的对象转移到另一个池中。生还者池的大小由参数 SurvivorRatio 确定。如果垃圾回收变成了瓶颈,您可以尝试定制生成池设置。要监控垃圾回收统计信息,使用 Tivoli Performance Viewer 中的对象统计信息或 verbose:gc 配置设置。输入下列值:
-XX:NewSize (lower bound)
-XX:MaxNewSize (upper bound)
-XX:SurvivorRatio=NewRatioSize
缺省值为:NewSize=2m MaxNewSize=32m SurvivorRatio=2。但是,如果 JVM 的堆大小大于 1GB,那么应该使用值:-XX:newSize=640m -XX:MaxNewSize=640m -XX:SurvivorRatio=16,或者将堆的总大小的 50% 到 60% 分配给新生成的池。

-Xminf
可以使用 -Xminf 来指定最小可用堆大小百分比。如果可用空间低于指定量,那么堆增长。在启用复位的方式中,此选项指定中间件和瞬态堆的可用空间的最小百分率。这是

-server | -client
基于 Sun 的 Java Development Kit(JDK)V1.4.2 中的 Java 热点技术引入了一种自适应 JVM,该 JVM 包含用于随着时间的推移而优化字节码执行的算法。JVM 以两种方式运行,分别为 -server 和 -client。如果您使用缺省值 -client 方式,将会获得较快的启动时间以及较小的内存占用量,但是获得的扩展性能也较低。如果有足够的时间来允许 HotSpot JVM 通过执行连续执行字节代码来热身,您可以使用 -server 方式以增强性能。在大多数情况下,应该使用 -server 方式,这将长时间地保持运行时执行高效运行。您可以监控进程大小以及服务器启动时间,来检查 -client 和 -server 之间的区别。
posted @ 2008-06-20 15:50 一凡 阅读(1580) | 评论 (0)编辑 收藏
    用MyEclipse写web工程时,总是显示jsp文件错误,很不爽,我们可以不让它进行语法检查:
    右键你的工程-- MyEclipse -- Exclude From Validation即可以去掉语法检查。
posted @ 2008-06-02 18:49 一凡 阅读(2127) | 评论 (0)编辑 收藏

请到这里下载我的录像:http://download.csdn.net/source/457437

jetty-7.0.0pre1在MyEclipse 5.0M1中应用配置

公司有一个项目需要使用一个嵌入式web server,在网上找了一通也没找着一篇完整的文章,现整理一份出来,便与大家参考。
需特别注意的是Jetty 6.0以前的版本和后来的是有差别的,以下为jetty-7.0.0pre1在myEclipse 5.0M1中应用配置步骤:
它的原理在网上很多,看源代码也好,我这里只说明应用

我的环境:
windows 2000 + JDK 1.5.0_08 + Eclipse 3.2.1 + MyEclipse 5.0M1
录像从第2步开始

1、下载jetty-7.0.0pre1
我下的是最新版的,下载地址:ftp://ftp.mortbay.org/pub/
解压到相应的目录,我解到了d:/

2、打开myEclipse,
   a.新建java工程JettyTest
   b.建立source folder src
   c.建立目录 conf, contexts, logs, webapps
   d.在webapps建立manage目录作为web工作目录
   e.在src下建包com.willpower.jetty
   f.将D:\jetty-7.0.0pre1\lib下的三个jar包加入工程的classpath, 将D:\jetty-7.0.0pre1\lib\jsp-2.1下的四个jar包加入工程的classpath
   g.copy D:\jetty-7.0.0pre1\etc下的jetty.xml, webdefault.xml和realm.properties到conf下
   h.copy D:\jetty-7.0.0pre1\contexts下的test.xml到contexts下并改名为manage.xml
   i.修改jetty.xml, manage.xml
   j.在webapps/manage下新建index.jsp
   k.在src/com.willpower.jetty 里新建Start.java并加入main(),加入以下代码:
      Server server = new Server(8080);
          server.setHandler(new DefaultHandler());
          XmlConfiguration cfg = null;
          try {
              cfg = new XmlConfiguration(new FileInputStream("./conf/jetty.xml"));
              cfg.configure(server);
              server.start(); 
              System.out.println("Jetty Started ...");
             
          } catch (FileNotFoundException e) {
              e.printStackTrace();
          } catch (SAXException e) {
              e.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          } catch (Exception e) {
              e.printStackTrace();
          }       
   l.运行Start类,用IE访问http://localhost:8080/, 点击/manage ---> org.mortbay.jetty.webapp.WebAppContext@bb05de
   刚才是因为忘记修改jetty.xml所致
  
   到此Jetty运行JSP成功
   停止服务
  
3、继续在Jetty中运行servlet
   a.在webapps/manage下建立WEB-INF, 并新建web.xml用于配置servlet, 并将contexts下的webdefalut.xml的内容copy到web.xml里
     修改contexts下的manage.xml
   b.在src下新建包com.willpower.servlet, 并新建servlet Manage                                                         
      request.setCharacterEncoding("GB2312");                                                                          
      String name = request.getParameter("name");                                                                       
      System.out.println("您提交的数据为:" + name);                                                                    
      System.out.println("OK");                                                                                         
   c.在web.xml里配置servlet, 将下面的代码加入web.xml的servlet配置区域
           <servlet>
            <servlet-name>Manage</servlet-name>
            <servlet-class>com.willpower.servlet.Manage</servlet-class>
            <load-on-startup>1</load-on-startup>
          </servlet>
       
          <servlet-mapping>
            <servlet-name>Manage</servlet-name>
            <url-pattern>/Manage</url-pattern>
          </servlet-mapping>
   d.修改webapps/manage/index.jsp,加入以下代码   
       <br>
        <form name="manage" method="Post" action="/manage/Manage">
        &nbsp;
        &nbsp;<input type="text" name="name" />
        <input type="submit" name="button2" value="提交" />
       
        </form>
   e.运行Start类,用IE访问http://localhost:8080/, 点击/manage ---> org.mortbay.jetty.webapp.WebAppContext@bb05de
   f.到此Jetty运行servlet成功  
   停止服务
    
     希望对大家有所帮助 2008-05-16 18:16
    
    
    
    
    
posted @ 2008-05-16 18:26 一凡 阅读(1779) | 评论 (0)编辑 收藏
  
    转自http://blog.csdn.net/shengbox/archive/2007/09/18/1789647.aspx
   照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的.
   静态存储分配是指在编译时就能确定 每个数据目标在运行时刻的存储空间需求,因而在编译时就可以给他们分配固定的内存空间.这种分配策略要求程序代码中不允许有可变数据结构(比如可变数组) 的存在,也不允许有嵌套或者递归的结构出现,因为它们都会导致编译程序无法计算准确的存储空间需求.
   栈式存储分配也可称为动态存储分配,是 由一个类似于堆栈的运行栈来实现的.和静态存储分配相反,在栈式存储方案中,程序对数据区的需求在编译时是完全未知的,只有到运行的时候才能够知道,但是 规定在运行中进入一个程序模块时,必须知道该程序模块所需的数据区大小才能够为其分配内存.和我们在数据结构所熟知的栈一样,栈式存储分配按照先进后出的 原则进行分配。
   静态存储分配要求在编译时能知道所有变量的存储要求,栈式存储分配要求在过程的入口处必须知道所有的存储要求,而堆式存储分 配则专门负责在编译时或运行时模块入口处都无法确定存储要求的数据结构的内存分配,比如可变长度串和对象实例.堆由大片的可利用块或空闲块组成,堆中的内 存可以按照任意顺序分配和释放. 
 堆和栈的比较
  上面的定义从编译原理的教材中总结而来,除静态存储分配之外,都显得很呆板和难以理解,下面撇开静态存储分配,集中比较堆和栈:
   从堆和栈的功能和作用来通俗的比较,堆主要用来存放对象的,栈主要是用来执行程序的.而这种不同又主要是由于堆和栈的特点决定的:
    在编程中,例如C/C++中,所有的方法调用都是通过栈来进行的,所有的局部变量,形式参数都是从栈中分配内存空间的。实际上也不是什么分配,只是从栈顶 向上用就行,就好像工厂中的传送带(conveyor belt)一样,Stack Pointer会自动指引你到放东西的位置,你所要做的只是把东西放 下来就行.退出函数的时候,修改栈指针就可以把栈中的内容销毁.这样的模式速度最快,当然要用来运行程序了.需要注意的是,在分配的时候,比如为一个即将 要调用的程序模块分配数据区时,应事先知道这个数据区的大小,也就说是虽然分配是在程序运行时进行的,但是分配的大小多少是确定的,不变的,而这个"大小 多少"是在编译时确定的,不是在运行时.
   堆是应用程序在运行的时候请求操作系统分配给自己内存,由于从操作系统管理的内存分配,所以在分配 和销毁时都要占用时间,因此用堆的效率非常低.但是堆的优点在于,编译器不必知道要从堆里分配多少存储空间,也不必知道存储的数据要在堆里停留多长的时 间,因此,用堆保存数据时会得到更大的灵活性。事实上,面向对象的多态性,堆内存分配是必不可少的,因为多态变量所需的存储空间只有在运行时创建了对象之 后才能确定.在C++中,要求创建一个对象时,只需用new命令编制相关的代码即可。执行这些代码时,会在堆里自动进行数据的保存.当然,为达到这种灵活 性,必然会付出一定的代价:在堆里分配存储空间时会花掉更长的时间!这也正是导致我们刚才所说的效率低的原因,看来列宁同志说的好,人的优点往往也是人的 缺点,人的缺点往往也是人的优点(晕~). 

 JVM中的堆和栈  
  JVM是基于堆栈的虚拟机.JVM为每个新创建的线程都分配一个堆栈.也就是说,对于一个Java程序来说,它的运行就是通过对堆栈的操作来完成的。堆栈以帧为单位保存线程的状态。JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。
   我们知道,某个线程正在执行的方法称为此线程的当前方法.我们可能不知道,当前方法使用的帧称为当前帧。当线程激活一个Java方法,JVM就会在线程的 Java堆栈里新压入一个帧。这个帧自然成为了当前帧.在此方法执行期间,这个帧将用来保存参数,局部变量,中间计算过程和其他数据.这个帧在这里和编译 原理中的活动纪录的概念是差不多的.
  从Java的这种分配机制来看,堆栈又可以这样理解:堆栈(Stack)是操作系统在建立某个进程时或者线程(在支持多线程的操作系统中是线程)为这个线程建立的存储区域,该区域具有先进后出的特性。
    每一个Java应用都唯一对应一个JVM实例,每一个实例唯一对应一个堆。应用程序在运行中所创建的所有类实例或数组都放在这个堆中,并由应用所有的线程 共享.跟C/C++不同,Java中分配堆内存是自动初始化的。Java中所有对象的存储空间都是在堆中分配的,但是这个对象的引用却是在堆栈中分配,也 就是说在建立一个对象时从两个地方都分配内存,在堆中分配的内存实际建立这个对象,而在堆栈中分配的内存只是一个指向这个堆对象的指针(引用)而已。
GC的思考
   Java为什么慢?JVM的存在当然是一个原因,但有人说,在Java中,除了简单类型(int,char等)的数据结构,其它都是在堆中分配内存(所以说Java的一切都是对象),这也是程序慢的原因之一。
    我的想法是(应该说代表TIJ的观点),如果没有Garbage Collector(GC),上面的说法就是成立的.堆不象栈是连续的空间,没有办法指 望堆本身的内存分配能够象堆栈一样拥有传送带般的速度,因为,谁会为你整理庞大的堆空间,让你几乎没有延迟的从堆中获取新的空间呢?
   这个时 候,GC站出来解决问题.我们都知道GC用来清除内存垃圾,为堆腾出空间供程序使用,但GC同时也担负了另外一个重要的任务,就是要让Java中堆的内存 分配和其他语言中堆栈的内存分配一样快,因为速度的问题几乎是众口一词的对Java的诟病.要达到这样的目的,就必须使堆的分配也能够做到象传送带一样, 不用自己操心去找空闲空间.这样,GC除了负责清除Garbage外,还要负责整理堆中的对象,把它们转移到一个远离Garbage的纯净空间中无间隔的 排列起来,就象堆栈中一样紧凑,这样Heap Pointer就可以方便的指向传送带的起始位置,或者说一个未使用的空间,为下一个需要分配内存的对象" 指引方向".因此可以这样说,垃圾收集影响了对象的创建速度,听起来很怪,对不对?
   那GC怎样在堆中找到所有存活的对象呢?前面说了,在建 立一个对象时,在堆中分配实际建立这个对象的内存,而在堆栈中分配一个指向这个堆对象的指针(引用),那么只要在堆栈(也有可能在静态存储区)找到这个引 用,就可以跟踪到所有存活的对象.找到之后,GC将它们从一个堆的块中移到另外一个堆的块中,并将它们一个挨一个的排列起来,就象我们上面说的那样,模拟 出了一个栈的结构,但又不是先进后出的分配,而是可以任意分配的,在速度可以保证的情况下,Isn't it great?
   但是,列宁同志 说了,人的优点往往也是人的缺点,人的缺点往往也是人的优点(再晕~~).GC()的运行要占用一个线程,这本身就是一个降低程序运行性能的缺陷,更何况 这个线程还要在堆中把内存翻来覆去的折腾.不仅如此,如上面所说,堆中存活的对象被搬移了位置,那么所有对这些对象的引用都要重新赋值.这些开销都会导致 性能的降低.
   此消彼长,GC()的优点带来的效益是否盖过了它的缺点导致的损失,我也没有太多的体会,Bruce Eckel 是Java的支持者,王婆卖瓜,话不能全信.个人总的感觉是,Java还是很慢,它的发展还需要时间.
  上面的体会是我看了TIJ.3rdEdition.Revision4.0中第四章之后得出的,内容和前面的有些不同.我没有看过侯捷的中文版本,但我觉得,在关键问题上,原版的TIJ的确更值得一读.所以和中文版配合起来学习是比较不错的选择.
   我只能算一个Java的初学者,没想到起了这么个题目,却受到这么多人的关注,欣喜之余,也决心尽力写好下面的每一篇.不过这一篇完了,我就该准备赴美签 证了,如果成功,那就要等到8月27号CS的研究生院开学之后,才有时间会开始研究下一章了,希望可以多从原版中获取一点经验. 
posted @ 2008-05-07 09:44 一凡 阅读(277) | 评论 (0)编辑 收藏
Linux 包含了一个叫 gdb 的 GNU 调试程序. gdb 是一个用来调试 C 和 C++ 程序的强力调试器. 它使你能在程序运行时观察程序的内部结构和内存的使用情况. 以下是 gdb 所提供的一些功能:
1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
3、当程序被停住时,可以检查此时你的程序中所发生的事。
4、动态的改变你程序的执行环境。
当你启动 gdb 后, 你能在命令行上指定很多的选项. 可以以下面的方式来运行 gdb gdb <fname>
当你用这种方式运行 gdb , 你能直接指定想要调试的程序. 这将告诉gdb 装入名为 fname 的可执行文件. 你也可以用 gdb 去检查一个因程序异常终止而产生的 core 文件, 或者与一个正在运行的程序相连. 你可以参考 gdb 指南页或在命令行上键入 gdb -h 得到一个有关这些选项的说明的简单列表.  
为调试编译代码
为了使 gdb 正常工作, 你必须使你的程序在编译时包含调试信息. 调试信息包含你程序里的每个变量的类型和在可执行文件里的地址映射以及源代码的行号.  gdb 利用这些信息使源代码和机器码相关联.
在编译时用 -g 选项打开调试选项.


命   令 描  述
file 装入想要调试的可执行文件.
kill 终止正在调试的程序.
list 列出产生执行文件的源代码的一部分.
next 执行一行源代码但不进入函数内部.
step 执行一行源代码而且进入函数内部.
run 执行当前被调试的程序
quit 终止 gdb
watch 使你能监视一个变量的值而不管它何时被改变.
break 在代码里设置断点, 这将使程序执行到这里时被挂起.
make 使你能不退出 gdb 就可以重新产生可执行文件.
shell 使你能不离开 gdb 就执行 UNIX shell 命令. 

(a)设置断点
break 20;---在第20行设置断点
break func;---在函数func的入口处设置断点
(b)取消断点
delete break 20;---取消第20行的断点
delete break func;---取消函数func入口处的断点
(c)运行代码
run;
r;
(d)显示变量或函数值
display;
p;
(e)单步执行
next;
n;
(f)跳步执行
step;
s;
(g)循环执行
continue;
c;
(h)列出运行栈内容
bt;
一个调试示例
——————

源程序:tst.c

     1 #include <stdio.h>
     2
     3 int func(int n)
     4 {
     5         int sum=0,i;
     6         for(i=0; i<n; i++)
     7         {
     8                 sum+=i;
     9         }
    10         return sum;
    11 }
    12
    13
    14 main()
    15 {
    16         int i;
    17         long result = 0;
    18         for(i=1; i<=100; i++)
    19         {
    20                 result += i;
    21         }
    22
    23        printf("result[1-100] = %d \n", result );
    24        printf("result[1-250] = %d \n", func(250) );
    25 }

编译生成执行文件:(Linux下)
cc -g tst.c -o tst

使用GDB调试:

gdb tst  <---------- 启动GDB
GNU gdb 5.1.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-SuSE-linux"...
(gdb) l     <-------------------- l命令相当于list,从第一行开始例出原码。
1        #include <stdio.h>
2
3        int func(int n)
4        {
5                int sum=0,i;
6                for(i=0; i<n; i++)
7                {
8                        sum+=i;
9                }
10               return sum;
(gdb)       <-------------------- 直接回车表示,重复上一次命令
11       }
12
13
14       main()
15       {
16               int i;
17               long result = 0;
18               for(i=1; i<=100; i++)
19               {
20                       result += i;   
(gdb) break 16    <-------------------- 设置断点,在源程序第16行处。
Breakpoint 1 at 0x8048496: file tst.c, line 16.
(gdb) break func  <-------------------- 设置断点,在函数func()入口处。
Breakpoint 2 at 0x8048456: file tst.c, line 5.
(gdb) info break  <-------------------- 查看断点信息。
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x08048496 in main at tst.c:16
2   breakpoint     keep y   0x08048456 in func at tst.c:5
(gdb) r           <--------------------- 运行程序,run命令简写
Starting program: /home/hchen/test/tst

Breakpoint 1, main () at tst.c:17    <---------- 在断点处停住。
17               long result = 0;
(gdb) n          <--------------------- 单条语句执行,next命令简写。
18               for(i=1; i<=100; i++)
(gdb) n
20                       result += i;
(gdb) n
18               for(i=1; i<=100; i++)
(gdb) n
20                       result += i;
(gdb) c          <--------------------- 继续运行程序,continue命令简写。
Continuing.
result[1-100] = 5050       <----------程序输出。

Breakpoint 2, func (n=250) at tst.c:5
5                int sum=0,i;
(gdb) n
6                for(i=1; i<=n; i++)
(gdb) p i        <--------------------- 打印变量i的值,print命令简写。
$1 = 134513808
(gdb) n
8                        sum+=i;
(gdb) n
6                for(i=1; i<=n; i++)
(gdb) p sum
$2 = 1
(gdb) n
8                        sum+=i;
(gdb) p i
$3 = 2
(gdb) n
6                for(i=1; i<=n; i++)
(gdb) p sum
$4 = 3
(gdb) bt        <--------------------- 查看函数堆栈。
#0  func (n=250) at tst.c:5
#1  0x080484e4 in main () at tst.c:24
#2  0x400409ed in __libc_start_main () from /lib/libc.so.6
(gdb) finish    <--------------------- 退出函数。
Run till exit from #0  func (n=250) at tst.c:5
0x080484e4 in main () at tst.c:24
24              printf("result[1-250] = %d \n", func(250) );
Value returned is $6 = 31375
(gdb) c     <--------------------- 继续运行。
Continuing.
result[1-250] = 31375    <----------程序输出。

Program exited with code 027. <--------程序退出,调试结束。
(gdb) q     <--------------------- 退出gdb。

posted @ 2008-04-18 15:51 一凡 阅读(482) | 评论 (0)编辑 收藏
  示例:

d=`date +%d`
echo 
"size" $'\t' "month" $'\t' "day" $'\t' "time" $'\t' "dir/file"
ls 
-*/* | awk '{if($5 > 0 && $7 == '$d') print $5 "\t" $6 "\t" $7 "\t" $8 "\t" $9}'

值得注意的是d=`date +%d`, 这里的引号不是“;”右边的键而是“tab”上面的那个
posted @ 2008-04-18 13:45 一凡 阅读(7594) | 评论 (3)编辑 收藏
仅列出标题
共21页: First 上一页 8 9 10 11 12 13 14 15 16 下一页 Last