??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲伊人久久大香线蕉苏妲己,亚洲成AV人片在,亚洲视频在线观看地址http://www.tkk7.com/byrtiger/category/32561.htmlLoving Javazh-cnTue, 16 Dec 2008 06:15:00 GMTTue, 16 Dec 2008 06:15:00 GMT60Agilehttp://www.tkk7.com/byrtiger/archive/2008/12/16/246549.htmlq风舞?/dc:creator>q风舞?/author>Tue, 16 Dec 2008 01:37:00 GMThttp://www.tkk7.com/byrtiger/archive/2008/12/16/246549.htmlhttp://www.tkk7.com/byrtiger/comments/246549.htmlhttp://www.tkk7.com/byrtiger/archive/2008/12/16/246549.html#Feedback0http://www.tkk7.com/byrtiger/comments/commentRss/246549.htmlhttp://www.tkk7.com/byrtiger/services/trackbacks/246549.html


]]>
Java面试?/title><link>http://www.tkk7.com/byrtiger/archive/2008/12/03/244078.html</link><dc:creator>q风舞?/dc:creator><author>q风舞?/author><pubDate>Wed, 03 Dec 2008 01:57:00 GMT</pubDate><guid>http://www.tkk7.com/byrtiger/archive/2008/12/03/244078.html</guid><wfw:comment>http://www.tkk7.com/byrtiger/comments/244078.html</wfw:comment><comments>http://www.tkk7.com/byrtiger/archive/2008/12/03/244078.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/byrtiger/comments/commentRss/244078.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/byrtiger/services/trackbacks/244078.html</trackback:ping><description><![CDATA[刚刚扑ֈ的面试题目。自己做了一下,反正挺惨不h睹的。脓出来想帮帮有需要的?<br /> q且问问Z么是q个l果呢?有的题的{案真的想不到啊~想不到?<br /> <br /> 一、判断题Q?0分) <br /> 1QJavaE序?创徏新的cd象用关键字newQ回收无用的cd象用关键字free?<br /> 2Q对象可以赋|只要使用赋值号Q等P卛_Q相当于生成了一个各属性与赋值对象相同的新对象?<br /> 3Q有的类定义时可以不定义构造函敎ͼ所以构造函C是必需的?<br /> 4Q类及其属性、方法可以同时有一个以上的修饰W来修饰?<br /> 5QJava的屏q坐标是以像素ؓ单位Q容器的左下角被定为坐标的L <br /> 6Q抽象方法必d抽象cMQ所以抽象类中的Ҏ都必L抽象Ҏ?<br /> 7QFinalcM的属性和Ҏ都必被final修饰W修饰?<br /> 8Q最l类不能z子类Q最l方法不能被覆盖?<br /> 9Q子c要调用父类的方法,必须使用super关键字?<br /> 10Q一个Javacd以有多个父类?<br /> 11Q如果p是父cParent的对象,而c是子cChild的对象,则语句c = p是正的?<br /> 12Q在java集合中,Vector和HashMap是线E安全的?<br /> 13Q当一个方法在q行q程中生一个异常,则这个方法会l止Q但是整个程序不一定终止运行?<br /> 14Q接口是Ҏ的类Q所以接口也可以l承Q子接口承父接口的所有常量和抽象Ҏ?<br /> 15Q用“+”可以实现字符串的拼接Q用- 可以从一个字W串中去除一个字W子丌Ӏ?<br /> <br /> 二、选择题(30分) <br /> 1、关于垃圾收集的哪些叙述是正的Q?nbsp;  Q: <br /> AQ程序开发者必自己创Z个线E进行内存释攄工作 <br /> BQ垃圾收集允许程序开发者明指定ƈ立即释放该内?<br /> CQ垃圾收集将查ƈ释放不再使用的内?<br /> DQ垃圾收集能够在期望的时间释放被java对象使用的内?<br /> 2、下面的哪些赋D句是不正的Q?nbsp;  Q: <br /> AQfloat f=11.1; <br /> BQdouble d=5.3E12; <br /> CQdouble d=3.14159; <br /> DQdouble d=3.14DQ?<br /> 3、下面关于变量及其范围的陈述哪些是不正确的(   Q: <br /> AQ实例变量是cȝ成员变量 <br /> BQ实例变量用关键字static声明 <br /> CQ在Ҏ中定义的局部变量在该方法被执行时创?<br /> DQ局部变量在使用前必被初始?<br /> 4、下列关于修饰符L的说法,错误的是Q?nbsp; Q: <br /> AQabstract不能与finalq列修饰同一个类 <br /> BQabstractcM不可以有private的成?<br /> CQabstractҎ必须在abstractcM <br /> DQstaticҎ中能处理非static的属?<br /> 5、容器Panel和Applet~省使用的布局~辑{略是(    Q: <br /> A、BorderLayout  B、FlowLayout      C、GridLayout      D、CardLayout <br /> 6、以下标识符中哪Ҏ不合法的(    )Q?<br /> A?BigMeaninglessName                     B?int <br /> C? st                                    D?1 <br /> 7、mainҎ是Java  ApplicationE序执行的入口点Q关于mainҎ的方法头以下哪项是合法的Q?nbsp;   Q: <br /> A?nbsp;   public  static  void  mainQ)    <br /> B?nbsp;   public  static  void   mainQString[ ]  argsQ?<br /> C?nbsp;   public  static int  mainQString[ ]  argQ?<br /> D?nbsp;   public  void  mainQString  arg[ ]Q?<br /> 8、执行完以下代码int [ ]  x = new  int[25]Q后Q以下哪说明是正确的(    Q: <br /> A?nbsp;   x[24]? <br /> B?nbsp;   x[24]未定?<br /> C?nbsp;   x[25]? <br /> D?nbsp;   x[0]为空 <br /> 9、以下代码段执行后的输出l果为(     Q: <br />        int  x=3Q?int  y=10Q?<br />        System.out.println(y%x); <br /> A? <br /> B? <br /> C? <br /> D? <br /> 10、以下哪个表辑ּ是不合法的(    Q: <br /> A、String  x=”Hello”;   int  y=9;   x+=y; <br /> B、String  x=”Hello”;   int  y=9;  if(x= =y)  { } <br /> C、String  x=”Hello”;  int  y=9;  x=x+y; <br /> D、String  x=null;  int  y=(x!=null)&&(x.length()>0) ? x.length : 0 <br /> 11、编译运行以下程序后Q关于输出结果的说明正确的是 Q?nbsp;   Q: <br />        public  class   Conditional{ <br />               public  static  void  main(String  args[  ]){ <br />                      int  x=4; <br />                      System.out.println(“value  is  “+ ((x>4) ? 99.9 :9)); <br /> } <br /> } <br /> A?nbsp;   输出l果为:value  is  99.99 <br /> B?nbsp;   输出l果为:value  is  9 <br /> C?nbsp;   输出l果为:value  is  9.0 <br /> D?nbsp;   ~译错误 <br /> 12、以下声明合法的是(     Q: <br /> A?nbsp;   default  String  sQ?<br /> B?nbsp;   public  final  static  native  int  w( ) <br /> C?nbsp;   abstract  double  dQ?<br /> D?nbsp;   abstract  final  double  hyperbolicCosine( ) <br /> 13、关于以下application的说明,正确的是Q?nbsp;   Q: <br /> 1Q?nbsp; class   StaticStuff <br /> 2Q?{ <br /> 3Q?nbsp;                 static  int  x=10Q?<br /> 4Q?nbsp;                 static  { x+=5Q} <br /> 5Q?nbsp;                 public  static  void  mainQString  args[ ]Q?<br /> 6Q?nbsp;                 { <br /> 7Q?nbsp;                      System.out.println(“x=” + x); <br /> 8Q?nbsp;                 } <br /> 9Q?nbsp;                 static  { x/=3;} <br /> 10.   } <br /> A?4行与9行不能通过~译Q因为缺方法名和返回类?nbsp; <br /> B?9行不能通过~译Q因为只能有一个静态初始化?<br /> C?~译通过Q执行结果ؓQx=5 <br /> D、编译通过Q执行结果ؓQx=3 <br /> 14、关于以下程序代码的说明正确的是Q?nbsp;  Q: <br /> 1Qclass  HasStatic{ <br /> 2Q?nbsp;   private  static  int  x=100Q?<br /> 3Q?nbsp;   public  static  void  main(String  args[  ]){ <br /> 4Q?nbsp;       HasStatic  hs1=new  HasStatic(  ); <br /> 5Q?nbsp;       hs1.x++; <br /> 6Q?nbsp;       HasStatic  hs2=new  HasStatic(  ); <br /> 7Q?nbsp;       hs2.x++; <br /> 8Q?nbsp;       hs1=new  HasStatic( ); <br /> 9Q?nbsp;       hs1.x++; <br /> 10Q?nbsp;      HasStatic.x- -; <br /> 11Q?nbsp;      System.out.println(“x=”+x); <br /> 12Q?nbsp;  } <br /> 13Q} <br /> A?行不能通过~译Q因为引用了U有静态变?<br /> B?0行不能通过~译Q因为x是私有静态变?<br /> C、程序通过~译Q输出结果ؓQx=103 <br /> D、程序通过~译Q输出结果ؓQx=102 <br /> 15、以下选项中@环结构合法的是(    Q: <br /> A、while (int  i<7){ <br />      i++; <br />      System.out.println(“i is “+i); <br /> } <br /> B、int  j=3; <br /> while(j){ <br />    System.out.println(“ j  is “+j); <br /> } <br /> C、int  j=0; <br /> for(int  k=0; j + k !=10; j++,k++){ <br />     System.out.println(“ j  is “+ j + “k  is”+ k); <br /> } <br /> D、int  j=0; <br /> do{ <br />         System.out.println( “j  is “+j++); <br />         if (j = = 3) {continue  loop;} <br /> }while  (j<10); <br /> <br /> 三、简{题Q?0分) <br /> 1.    写出下列E序的运行结?<br /> public class Cat <br /> {   <br />   void mi( ) throws NullPointerException <br />   { <br />     System.out.println( “Cat mi mi .. “ ); <br />   } <br /> } <br /> public class SmallCat extends Cat <br /> {int i=8; <br />   void mi( ) throws Exception <br />   { <br />     System.out.println( “SmallCat mi mi .. “ ); <br />   } <br />   public static void main( String[] a ) throws Exception <br />   { <br />     Cat cat = new SmallCat(); <br />     cat.mi(); <br />   } <br /> } <br /> <br /> <br /> 写出下列E序的运行结?<br /> interface Playable { <br />     void play(); <br /> } <br /> interface Bounceable { <br />     void play(); <br /> } <br /> interface Rollable extends Playable, Bounceable { <br />     Ball ball = new Ball("PingPang"); <br /> } <br /> class Ball implements Rollable { <br />     private String name; <br />     public String getName() { <br />         return name; <br />     } <br />     public Ball(String name) { <br />         this.name = name;        <br />     } <br />    public void play() { <br />         ball = new Ball("Football"); <br />         System.out.println(ball.getName()); <br />     } <br /> } <br /> <br /> 写出下列E序的运行结?<br /> class Value{ <br /> public int i = 15; <br /> } <br /> public class Test{ <br /> public static void main(String argv[]){ <br />        Test t = new Test(); <br />     t.first(); <br />    } <br /> public void first(){ <br />        int i = 5; <br />        Value v = new Value(); <br />       v.i = 25; <br />       second(v, i); <br />       System.out.println(v.i); <br />    } <br /> public void second(Value v, int i){ <br />       i = 0; <br />        v.i = 20; <br />      Value val = new Value(); <br />         v = val; <br />         System.out.println(v.i + " " + i); <br />       } <br /> } <br /> <br /> <br /> 写出下列E序的运行结?<br /> class MyThread extends Thread{ <br /> public void run(){ <br /> System.out.println("MyThread: run()"); <br /> } <br /> public void start(){ <br /> System.out.println("MyThread: start()"); <br />     } <br /> } <br /> class MyRunnable implements Runnable{ <br /> public void run(){ <br /> System.out.println("MyRunnable: run()"); <br />     } <br /> public void start(){ <br /> System.out.println("MyRunnable: start()"); <br />    } <br /> } <br /> public class MyTest { <br /> public static void main(String args[]){ <br /> MyThread myThread  =  new MyThread(); <br /> MyRunnable myRunnable = new MyRunnable(); <br /> Thread thread  =  new Thread(myRunnable); <br /> myThread.start(); <br /> thread.start(); <br /> } <br /> } <img src ="http://www.tkk7.com/byrtiger/aggbug/244078.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/byrtiger/" target="_blank">q风舞?/a> 2008-12-03 09:57 <a href="http://www.tkk7.com/byrtiger/archive/2008/12/03/244078.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转蝲QJDK5.0垃圾攉优化?-Don't Pausehttp://www.tkk7.com/byrtiger/archive/2008/12/03/244075.htmlq风舞?/dc:creator>q风舞?/author>Wed, 03 Dec 2008 01:51:00 GMThttp://www.tkk7.com/byrtiger/archive/2008/12/03/244075.htmlhttp://www.tkk7.com/byrtiger/comments/244075.htmlhttp://www.tkk7.com/byrtiger/archive/2008/12/03/244075.html#Feedback0http://www.tkk7.com/byrtiger/comments/commentRss/244075.htmlhttp://www.tkk7.com/byrtiger/services/trackbacks/244075.html一、参考资料:

  1. Tuning Garbage Collection with the 5.0 Java Virtual Machine 官方指南?
  2. Hotspot memory management whitepaper 官方白皮书?
  3. Java Tuning White Paper 官方文档?
  4. FAQ about Garbage Collection in the Hotspot  官方FAQQJVM1.4.2?
  5. Java HotSpot 虚拟Z的垃圾收?/font> JavaOne2004上的中文ppt
  6. A Collection of JVM Options JVM选项的超完整攉?

二、基本概?/strong>

1、堆(Heap)

JVM理的内存叫堆。在32Bit操作pȝ上有1.5G-2G的限Ӟ?4Bit的就没有?

JVM初始分配的内存由-Xms指定Q默认是物理内存?/64但小?G?

JVM最大分配的内存?Xmx指定Q默认是物理内存?/4但小?G?

默认IZ堆内存小?0%ӞJVM׃增大堆直?Xmx的最大限Ӟ可以?XX:MinHeapFreeRatio=指定?
默认IZ堆内存大?0%ӞJVM会减堆直到-Xms的最限Ӟ可以?XX:MaxHeapFreeRatio=指定?

服务器一般设|?Xms?Xmx相等以避免在每次GC 后调整堆的大,所以上面的两个参数没啥用?nbsp;

2.基本攉法

  1. 复制Q将堆内分成两个相同I间Q从?ThreadLocal的对象,静态对象)开始访问每一个关联的z跃对象Q将I间A的活跃对象全部复制到I间BQ然后一ơ性回收整个空间A?br /> 因ؓ只访问活跃对象,所有活动对象复制走之后清I整个空_不用去访问死对象Q所以遍历空间的成本较小Q但需要巨大的复制成本和较多的内存?
  2. 标记清除(mark-sweep)Q?/strong>攉器先从根开始访问所有活跃对象,标记为活跃对象。然后再遍历一ơ整个内存区域,把所有没有标记活跃的对象q行回收处理。该法遍历整个I间的成本较大暂停时间随I间大小U性增大,而且整理后堆里的片很多?
  3. 标记整理(mark-sweep-compact)Q?/strong>l合了上qC者的做法和优点,先标记活跃对象,然后其合ƈ成较大的内存块?

    可见Q没有免费的午餐Q无论采用复制还是标记清除算法,自动的东襉K要付出很大的性能代h?

3.分代

    分代是Java垃圾攉的一大亮点,Ҏ对象的生命周期长短,把堆分ؓ3个代QYoungQOld和PermanentQ根据不同代的特炚w用不同的攉法Q扬镉K短也?

Young(Nursery)Q年M。研I表明大部分对象都是朝生暮死Q随生随灭的。因此所有收集器都ؓq轻代选择了复制算法?br />     复制法优点是只讉Kz跃对象Q缺Ҏ复制成本高。因为年M只有量的对象能熬到垃圾攉Q因此只需量的复制成本。而且复制攉器只讉Kz跃对象Q对那些占了最大比率的d象视而不见,充分发挥了它遍历I间成本低的优点?

    Young的默认gؓ4MQ随堆内存增大,Uؓ1/15QJVM会根据情况动态管理其大小变化?br />     -XX:NewRatio= 参数可以讄Young与Old的大比例,-server旉认ؓ1:2Q但实际上young启动时远低于q个比率Q如果信不过JVMQ也可以?Xmn性规定其大小Q有文档推荐设ؓHeapd的1/4?

    Young的大非帔R帔R要,?#8220;后面暂停旉优先攉?#8221;的论q?

    Young里面又分?个区域,一个EdenQ所有新建对象都会存在于该区Q两个Survivor区,用来实施复制法。每ơ复制就是将Eden和第一块Survior的活对象复制到第2块,然后清空Eden与第一块Survior。Eden与Survivor的比例由-XX:SurvivorRatio=讄Q默认ؓ32。Survivio大了会浪费,了的话Q会使一些年d象潜逃到老h区,引v老h区的不安Q但q个参数Ҏ能q不重要?nbsp;

Old(Tenured)Q年老代。年M的对象如果能够挺q数ơ收集,׃q入老h区。老hZ用标记整理算法。因h区的对象都没那么ҎȝQ采用复制算法就要反复的复制对象Q很不合,只好采用标记清理法Q但标记清理法其实也不LQ每ơ都要遍历区域内所有对象,所以还是没有免费的午餐啊?

-XX:MaxTenuringThreshold=讄熬过q轻代多次攉后移入老h区,CMS中默认ؓ0Q熬q第一ơGCp{入,可以?XX:+PrintTenuringDistribution查看?

PermanentQ持久代?/strong>装蝲Class信息{基数据Q默?4MQ如果是cd多很多的服务E序Q需要加大其讄-XX:MaxPermSize=Q否则它满了之后会引起fullgc()或Out of Memory?注意SpringQHibernateq类喜欢AOP动态生成类的框枉要更多的持久代内存?

4.minor/major collection

    每个代满了之后都会促发collectionQ(另外Concurrent Low Pause Collector默认在老h?8%的时候促?。GC用较高的频率对youngq行扫描和回Ӟq种叫做minor collection?br /> 而因为成本关pdOld的检查回攉率要低很多,同时对Young和Old的收集称为major collection?br />     System.gc()会引发major collectionQ?XX:+DisableExplicitGC止它,或设为CMSq发-XX:+ExplicitGCInvokesConcurrent?

5.结

Young -- minor collection -- 复制法

Old(Tenured) -- major colletion -- 标记清除/标记整理法

三、收集器

1.古老的串行攉?Serial Collector)

    使用 -XX:+UseSerialGCQ策略ؓq轻代串行复Ӟq老代串行标记整理?

2.吞吐量优先的q行攉?Throughput Collector)

    使用 -XX:+UseParallelGC Q也是JDK5 -server的默认倹{策略ؓQ?br />     1.q轻代暂停应用程序,多个垃圾攉U程q行的复制收集,U程数默认ؓCPU个数QCPU很多Ӟ可用–XX:ParallelGCThreads=减少U程数?br />     2.q老代暂停应用E序Q与串行攉器一P单垃圾收集线E标记整理?

    所以需?+的CPU时才会优于串行收集器Q适用于后台处理,U学计算?

    可以使用-XX:MaxGCPauseMillis= ?-XX:GCTimeRatio 来调整GC的时间?

3.暂停旉优先的ƈ发收集器(Concurrent Low Pause Collector-CMS)

    前面说了q么多,都是Zq节做铺?.....

    使用-XX:+UseConcMarkSweepGCQ策略ؓQ?br />     1.q轻代同h暂停应用E序Q多个垃圾收集线Eƈ行的复制攉?br />     2.q老代则只有两ơ短暂停Q其他时间应用程序与攉U程q发的清除?

3.1 q老代详述

    q行(Parallel)与ƈ?Concurrent)仅一字之差,q行指多条垃圾收集线Eƈ行,q发指用LE与垃圾攉U程q发Q程序在l箋q行Q而垃圾收集程序运行于另一个个CPU上?

    q发攉一开始会很短暂的停止一ơ所有线E来开始初始标记根对象Q然后标记线E与应用U程一起ƈ发运行,最后又很短的暂停一ơ,多线E?strong>q行的重新标C前可能因为ƈ发而漏掉的对象Q然后就开始与应用E序q发的清除过E。可见,最长的两个遍历q程都是与应用程序ƈ发执行的Q比以前的串行算法改q太多太多了Q!Q?

    串行标记清除是等q老代满了再开始收集的Q而ƈ发收集因与应用程序一赯行,如果满了才收集,应用E序无内存可用Q所以系l默?8%满的时候就开始收集。内存已讑־较大Q吃内存又没有这么快的时候,可以?XX:CMSInitiatingOccupancyFraction=恰当增大该比率?

3.2 q轻代详q?/strong>

   可惜对年M的复制收集,依然必须停止所有应用程序线E,原理如此Q只能靠多CPUQ多攉U程q发来提高收集速度Q但除非你的Server独占整台服务器,否则如果服务器上本nq有很多其他U程Ӟ切换h速度?.... 所以,搞到最后,暂停旉的瓶颈就落在了年M的复制算法上?

    因此Young的大设|挺重要的,大点׃用频JGCQ而且增大GC的间隔后Q可以让多点对象自己L而不用复制了。但Young增大ӞGC造成的停时间攀升得非常恐怖,比如在我的机器上Q默?M的YoungQ只需要几毫秒的时_64M升?0毫秒Q而升?56MӞp?00毫秒了,峰D会攀到恐怖的800ms。谁叫复制算法,要等Young满了才开始收集,开始收集就要停止所有线E呢?

3.3 持久?/strong>

可设|?XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabledQCMS攉持久代的c,而不是fullgcQnetbeans5.5 performance文档的推荐?/code>

4.增量(train法)攉?Incremental Collector)

已停止维护,–Xincgc选项默认转ؓq发攉器?

四、暂停时间显C?/strong>

 加入下列参数 (请将PrintGC和Details中间的空格去掉,CSDN很怪的认ؓ是禁止字句) 

-verbose:gc -XX:+PrintGC Details  -XX:+PrintGCTimeStamps

会程序运行过E中显C如下输?

 9.211: [GC 9.211: [ParNew: 7994K->0K(8128K), 0.0123935 secs] 427172K->419977K(524224K), 0.0125728 secs]

 昄在程序运行的9.211U发生了Minor的垃圾收集,前一D|据针Ҏ生区Q从7994k整理?kQ新生区dؓ8128kQ程序暂停了12msQ而后一D|据针Ҏ个堆?

对于q老代的收集,暂停发生在下面两个阶D,CMS-remark的中断是17毫秒Q?

[GC [1 CMS-initial-mark: 80168K(196608K)] 81144K(261184K), 0.0059036 secs] 

[1 CMS-remark: 80168K(196608K)] 82493K(261184K),0.0168943 secs]

再加两个参数 -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTimeҎ停时间看得更清晰?

五、真正不停的BEA JRockit 与Sun RTS2.0

   Bea?a >JRockit 5.0 R27 的特色之一是动态决定的垃圾攉{略Q用户可以决定自己关心的是吞吐量Q暂停时间还是确定的暂停旉Q再由JVM在运行时动态决定、改变改变垃圾收集策略?br />    
   它的Deterministic GC的选项?Xgcprio: deterministicQ号U可以把暂停可以控制?0-30毫秒Q非常的牛,一句Deterministic道尽了RealTime的真谛?不过l看一下文档,30ms的测试环境是1 GB heap ?q_  30% 的活跃对?也就?00M)zd对象Q? ?Xeon 3.6 GHz  4G内存 Q或者是4 个Xeon 2.0 GHzQ?G内存?

  最可惜JRockt的license很奇怪,虽然qx使用免费Q但q个30ms的选项需要购买整个Weblogic Real Time Server的license?nbsp;

  其他免费选项Q有Q?/p>

  • -Xgcprio:pausetime -Xpausetarget=210ms 
      因ؓ免费Q所以最低只能设|到200ms pause target?nbsp;200ms是Sun认ؓReal-Time的分界线?
  • -Xgc:gencon
    普通的q发做法Q效率也不错?

  JavaOne2007上有Sun?Java Real-Time System 2.0 的介l,RTS2.0ZJDK1.5Q在Real-Time  Garbage Collctor上又有改q,但还在beta版状态,只供lOEMQ更怪?

六、JDK 6.0的改q?/strong>

因ؓJDK5.0在Young较大时的表现q是不够让h满意Q又l箋看JDK6.0的改q,l果E稍失望Q不涉及我最头痛的年M复制攉改良?

1.q老代的标?清除攉Qƈ行执行标?/strong>
  JDK5.0只开了一条收集进E与应用U程q发标识Q?.0可以开多条攉U程来做标识Q羃短标识老h区所有活动对象的旉?

2.加大了Young区的默认大小
默认大小?M加到16MQ从堆内存的1/15增加?/7

3.System.gc()可以与应用程序ƈ发执?/strong>
使用-XX:+ExplicitGCInvokesConcurrent 讄

七、小l?/strong>

1. JDK5.0/6.0

对于服务器应用,我们使用Concurrent Low Pause CollectorQ对q轻代,暂停时多U程q行复制攉Q对q老代Q收集器与应用程序ƈ行标?-整理攉Q以辑ֈ量短的垃圾攉旉?

本着没有深刻试前不要胡׃化的宗旨Q命令行属性只需单写为:

-server -Xms<heapsize>M -Xmx<heapsize>M -XX:+UseConcMarkSweepGC  -XX:+PrintGC Details  -XX:+PrintGCTimeStamps

然后要根据应用的情况Q在试软g辅助可以下看看有没有JVM的默认值和自动理做的不够的地方可以调_?xmn 设Young的大,-XX:MaxPermSize设持久代大小{?

2. JRockit 6.0 R27.2

但因为JDK5的测试结果实在不能满意,后来又尝试了JRockitQM效果要好些?br />  JRockit的特Ҏ动态垃圾收集器是根据用户关心的特征动态决定收集算法的Q参数如?/p>

 -Xms<heapsize>M -Xmx<heapsize>M -Xgcprio:pausetime -Xpausetarget=200ms -XgcReport -XgcPause -Xverbose:memory


]]>
Java 垃圾回收 http://www.tkk7.com/byrtiger/archive/2008/12/03/244070.htmlq风舞?/dc:creator>q风舞?/author>Wed, 03 Dec 2008 01:41:00 GMThttp://www.tkk7.com/byrtiger/archive/2008/12/03/244070.htmlhttp://www.tkk7.com/byrtiger/comments/244070.htmlhttp://www.tkk7.com/byrtiger/archive/2008/12/03/244070.html#Feedback0http://www.tkk7.com/byrtiger/comments/commentRss/244070.htmlhttp://www.tkk7.com/byrtiger/services/trackbacks/244070.html new Draggable("related_topics");

1.垃圾攉法的核心思想

  Java语言建立了垃圾收集机Ӟ用以跟踪正在使用的对象和发现q回收不再?引用)的对象。该机制可以有效防范动态内存分配中可能发生的两个危险:因内存垃圾过多而引发的内存耗尽Q以及不恰当的内存释放所造成的内存非法引用?/font>

  垃圾攉法的核心思想是:对虚拟机可用内存I间Q即堆空间中的对象进行识别,如果对象正在被引用,那么U其为存zd象,反之Q如果对象不再被引用Q则为垃圑֯象,可以回收其占据的I间Q用于再分配。垃圾收集算法的选择和垃圾收集系l参数的合理调节直接影响着pȝ性能Q因此需要开发h员做比较深入的了解?/font>

2.触发主GC(Garbage Collector)的条?/strong>

  JVMq行ơGC的频率很?但因UGC占用旉极短,所以对pȝ产生的媄响不大。更值得x的是主GC的触发条?因ؓ它对pȝ影响很明显。ȝ来说,有两个条件会触发主GC:
 

  ①当应用E序I闲?x有应用线E在q行?GC会被调用。因为GC在优先最低的U程中进?所以当应用忙时,GCU程׃会被调用,但以下条仉外?/font>

  ②Java堆内存不x,GC会被调用。当应用U程在运?q在q行q程中创建新对象,若这时内存空间不?JVM׃强制地调用GCU程,以便回收内存用于新的分配。若GC一ơ之后仍不能满内存分配的要?JVM会再q行两次GC作进一步的试,若仍无法满要求,?JVM报“out of memory”的错?Java应用停止?/font>

  ׃是否q行主GC由JVMҎpȝ环境军_,而系l环境在不断的变化当?所以主GC的运行具有不定?无法预计它何时必然出?但可以确定的是对一个长期运行的应用来说,其主GC是反复进行的?/font>

3.减少GC开销的措?/strong>

  Ҏ上述GC的机?E序的运行会直接影响pȝ环境的变?从而媄响GC的触发。若不针对GC的特点进行设计和~码,׃出现内存ȝ{一pd负面影响。ؓ了避免这些媄?基本的原则就是尽可能地减垃圑֒减少GCq程中的开销。具体措施包括以下几个方?

  (1)不要昑ּ调用System.gc()

  此函数徏议JVMq行主GC,虽然只是而非一?但很多情况下它会触发主GC,从而增加主GC的频?也即增加了间歇性停的ơ数?/font>

  (2)量减少临时对象的?/font>

  临时对象在蟩出函数调用后,会成为垃?用临时变量q当于减少了垃圄产生,从而g长了出现上述W二个触发条件出现的旉,减少了主GC的机会?/font>

  (3)对象不用时最好显式置为Null

  一般而言,为Null的对象都会被作ؓ垃圾处理,所以将不用的对象显式地设ؓNull,有利于GC攉器判定垃?从而提高了GC的效率?/font>

  (4)量使用StringBuffer,而不用String来篏加字W串(详见blog另一文章JAVA中String与StringBuffer)

  ׃String是固定长的字W串对象,累加String对象?q在一个String对象中扩?而是重新创徏新的String对象,如Str5=Str1+Str2+Str3+Str4,q条语句执行q程中会产生多个垃圾对象,因ؓҎ?#8220;+”操作旉必须创徏新的String对象,但这些过渡对象对pȝ来说是没有实际意义的,只会增加更多的垃圾。避免这U情况可以改用StringBuffer来篏加字W串,因StringBuffer是可变长?它在原有基础上进行扩?不会产生中间对象?/font>

  (5)能用基本cd如Int,Long,׃用Integer,Long对象

  基本cd变量占用的内存资源比相应对象占用的少得多,如果没有必要,最好用基本变量?/font>

  (6)量用静态对象变?/font>

  静态变量属于全局变量,不会被GC回收,它们会一直占用内存?/font>

  (7)分散对象创徏或删除的旉

  集中在短旉内大量创建新对象,特别是大对象,会导致突焉要大量内?JVM在面临这U情冉|,只能q行主GC,以回收内存或整合内存片,从而增加主GC的频率。集中删除对?道理也是一L。它使得H然出现了大量的垃圾对象,I闲I间必然减少,从而大大增加了下一ơ创建新对象时强制主GC的机会?/font>

4.gc与finalizeҎ

  ⑴gcҎh垃圾回收

  使用System.gc()可以不管JVM使用的是哪一U垃圑֛收的法Q都可以hJava的垃圑֛收。需要注意的是,调用System.gc()也仅仅是一个请求。JVM接受q个消息后,q不是立卛_垃圾回收Q而只是对几个垃圾回收法做了加权Q垃圾回收操作Ҏ发生Q或提早发生Q或回收较多而已?/font>

  ⑵finalizeҎ透视垃圾攉器的q行

  在JVM垃圾攉器收集一个对象之?Q一般要求程序调用适当的方法释放资源,但在没有明确释放资源的情况下QJava提供了缺省机制来l止化该对象释放资源Q这个方法就是finalize()。它的原型ؓQ?/font>

  protected void finalize() throws Throwable

  在finalize()Ҏq回之后Q对象消失,垃圾攉开始执行。原型中的throws Throwable表示它可以抛ZQ何类型的异常?/font>

  因此Q当对象卛_被销毁时Q有旉要做一些善后工作。可以把q些操作写在finalize()Ҏ里?/font>

 

java 代码
  1. protected void finalize()    
  2.    {    
  3.    // finalization code here    
  4.    }  

 

⑶代码示?br />

java 代码
  1. class Garbage{    
  2.    int index;    
  3.    static int count;    
  4.   
  5.    Garbage() {    
  6.    count++;    
  7.    System.out.println("object "+count+" construct");    
  8.    setID(count);    
  9.    }    
  10.   
  11.    void setID(int id) {    
  12.    index=id;    
  13.    }    
  14.   
  15.    protected void finalize() //重写finalizeҎ    
  16.    {    
  17.    System.out.println("object "+index+" is reclaimed");    
  18.    }    
  19.   
  20.    public static void main(String[] args)    
  21.    {    
  22.    new Garbage();    
  23.    new Garbage();    
  24.    new Garbage();    
  25.    new Garbage();    
  26.    System.gc(); //hq行垃圾攉?nbsp;   
  27.    }    
  28.   
  29.  }  

5.Java 内存泄漏
  ׃采用了垃圑֛收机ӞM不可辑֯?对象不再被引?都可以由垃圾攉U程回收。因此通常说的Java 内存泄漏其实是指无意识的、非故意的对象引用,或者无意识的对象保持。无意识的对象引用是指代码的开发h员本来已l对对象使用完毕Q却因ؓ~码的错误而意外地保存了对该对象的引用(q个引用的存在ƈ不是~码人员的主观意?Q从而得该对象一直无法被垃圾回收器回收掉Q这U本来以为可以释放掉的却最l未能被释放的空间可以认为是?#8220;泄漏?#8221;?/font>

  考虑下面的程?在ObjStackcM,使用push和popҎ来管理堆栈中的对象。两个方法中的烦?index)用于指示堆栈中下一个可用位|。pushҎ存储Ҏ对象的引用ƈ增加索引?而popҎ减小索引值ƈq回堆栈最上面的元素。在mainҎ?创徏了容量ؓ64的栈,q?4ơ调用pushҎ向它d对象,此时index的gؓ64,随后?2ơ调用popҎ,则index的值变?2,出栈意味着在堆栈中的空间应该被攉。但事实?popҎ只是减小了烦引?堆栈仍然保持着寚w些对象的引用。故32个无用对象不会被GC回收,造成了内存渗漏?/font>

 

java 代码
public class ObjStack {    
  1.    private Object[] stack;    
  2.    private int index;    
  3.    ObjStack(int indexcount) {    
  4.    stack = new Object[indexcount];    
  5.    index = 0;    
  6.    }    
  7.    public void push(Object obj) {    
  8.    stack[index] = obj;    
  9.    index++;    
  10.    }    
  11.    public Object pop() {    
  12.    index--;    
  13.    return stack[index];    
  14.    }    
  15.    }    
  16.    public class Pushpop {    
  17.    public static void main(String[] args) {    
  18.    int i = 0;    
  19.    Object tempobj;    
  20.   
  21. //new一个ObjStack对象Qƈ调用有参构造函数。分配stack Obj数组的空间大ؓ64Q可以存64个对象,?开始存?  
  22.    ObjStack stack1 = new ObjStack(64);   
  23.   
  24.    while (i < 64)    
  25.    {    
  26.    tempobj = new Object();//循环new Obj对象Q把每次循环的对象一一存放在stack Obj数组中?nbsp;   
  27.    stack1.push(tempobj);    
  28.    i++;    
  29.    System.out.println("W? + i + "ơ进? + "\t");    
  30.    }    
  31.   
  32.    while (i > 32)    
  33.    {    
  34.    tempobj = stack1.pop();//q里造成了空间的费?nbsp;   
  35.    //正确的popҎ可改成如下所指示,当引用被q回?堆栈删除对他们的引用,因此垃圾攉器在以后可以回收他们?nbsp;   
  36.    /*   
  37.    * public Object pop() {index - -;Object temp = stack [index];stack [index]=null;return temp;}   
  38.    */    
  39.    i--;    
  40.    System.out.println("W? + (64 - i) + "ơ出? + "\t");    
  41.    }    
  42.    }    
  43.    }  

 

6.如何消除内存泄漏

  虽然Java虚拟?JVM)及其垃圾攉?garbage collectorQGC)负责理大多数的内存dQJava软gE序中还是有可能出现内存泄漏。实际上Q这在大型项目中是一个常见的问题。避免内存泄漏的W一步是要弄清楚它是如何发生的。本文介l了~写Java代码的一些常见的内存泄漏陷阱Q以及编写不泄漏代码的一些最佛_c一旦发生了内存泄漏Q要指出造成泄漏的代码是非常困难的。因此本文还介绍了一U新工具Q用来诊断泄漏ƈ指出Ҏ原因。该工具的开销非常,因此可以使用它来L处于生中的pȝ的内存泄漏?/font>

  垃圾攉器的作用

  虽然垃圾攉器处理了大多数内存管理问题,从而ɾ~程人员的生zd得更L了,但是~程人员q是可能犯错而导致出现内存问题。简单地_GC循环地跟t所有来?#8220;?#8221;对象(堆栈对象、静态对象、JNI句柄指向的对象,诸如此类)的引用,q将所有它所能到辄对象标记为活动的。程序只可以操纵q些对象;其他的对象都被删除了。因为GC使程序不可能到达已被删除的对象,q么做就是安全的?/font>

  虽然内存理可以说是自动化的Q但是这q不能ɾ~程人员免受思考内存管理问题之苦。例如,分配(以及释放)内存M有开销Q虽然这U开销对编Eh员来说是不可见的。创Z太多对象的程序将会比完成同样的功能而创建的对象却比较少的程序更慢一?在其他条件相同的情况??/font>

  而且Q与本文更ؓ密切相关的是Q如果忘?#8220;释放”先前分配的内存,可能造成内存泄漏。如果程序保留对永远不再使用的对象的引用Q这些对象将会占用ƈ耗尽内存Q这是因动化的垃圾收集器无法证明q些对象不再用。正如我们先前所说的Q如果存在一个对对象的引用,对象p定义为活动的Q因此不能删除。ؓ了确保能回收对象占用的内存,~程人员必须保该对象不能到达。这通常是通过对象字D设|ؓnull或者从集合(collection)中移除对象而完成的。但是,注意Q当局部变量不再用时Q没有必要将其显式地讄为null。对q些变量的引用将随着Ҏ的退自动清除?/font>

  概括地说Q这是内存托管语言中的内存泄漏产生的主要原因:保留下来却永q不再用的对象引用?/font>

  典型泄漏

  既然我们知道了在Java中确实有可能发生内存泄漏Q就让我们来看一些典型的内存泄漏及其原因?/font>

  全局集合

  在大的应用程序中有某U全局的数据储存库是很常见的,例如一个JNDI树或一个会话表。在q些情况下,必须注意理储存库的大小。必L某种机制从储存库中移除不再需要的数据?/font>

  q可能有多种ҎQ但是最常见的一U是周期性运行的某种清除d。该d验证储存库中的数据QƈU除M不再需要的数据?/font>

  另一U管理储存库的方法是使用反向链接(referrer)计数。然后集合负责统计集合中每个入口的反向链接的数目。这要求反向链接告诉集合何时会退出入口。当反向链接数目为零Ӟ该元素就可以从集合中U除了?/font>

  ~存

  ~存是一U数据结构,用于快速查扑ַl执行的操作的结果。因此,如果一个操作执行v来很慢,对于常用的输入数据,可以将操作的结果缓存,q在下次调用该操作时使用~存的数据?/font>

  ~存通常都是以动态方式实现的Q其中新的结果是在执行时d到缓存中的。典型的法是:

  查结果是否在~存中,如果在,p回结果?/font>

  如果l果不在~存中,p行计?/font>

  计出来的l果d到缓存中Q以便以后对该操作的调用可以使用?/font>

  该算法的问题(或者说是潜在的内存泄漏)出在最后一步。如果调用该操作时有相当多的不同输入Q就有相当多的l果存储在缓存中。很明显q不是正的Ҏ?/font>

  Z预防q种h潜在破坏性的设计Q程序必ȝ保对于缓存所使用的内存容量有一个上限。因此,更好的算法是Q?/font>

  查结果是否在~存中,如果在,p回结果?/font>

  如果l果不在~存中,p行计?/font>

  如果~存所占的I间q大Q就U除~存最久的l果?/font>

  计出来的l果d到缓存中Q以便以后对该操作的调用可以使用?/font>

  通过始终U除~存最久的l果Q我们实际上q行了这L假设Q在来Q比L存最久的数据Q最q输入的数据更有可能用到。这通常是一个不错的假设?/font>

  新算法将保~存的容量处于预定义的内存范围之内。确切的范围可能很难计算Q因为缓存中的对象在不断变化Q而且它们的引用包|万象。ؓ~存讄正确的大是一w常复杂的dQ需要将所使用的内存容量与索数据的速度加以q?/font>

  解决q个问题的另一U方法是使用java.lang.ref.SoftReferencec跟t缓存中的对象。这U方法保证这些引用能够被U除Q如果虚拟机的内存用而需要更多堆的话?/font>

  ClassLoader

  Java ClassLoaderl构的用ؓ内存泄漏提供了许多可乘之机。正是该l构本n的复杂性ClassLoader在内存泄漏方面存在如此多的问题。ClassLoader的特别之处在于它不仅涉及“常规”的对象引用,q涉及元对象引用Q比如:字段、方法和cR这意味着只要有对字段、方法、类或ClassLoader的对象的引用QClassLoader׃ȝ在JVM中。因为ClassLoader本n可以兌许多cd光态字D,所以就有许多内存被泄漏了?/font>

  定泄漏的位|?/font>

  通常发生内存泄漏的第一个迹象是Q在应用E序中出COutOfMemoryError。这通常发生在您最不愿意它发生的生产环境中Q此时几乎不能进行调试。有可能是因为测试环境运行应用程序的方式与生产系l不完全相同Q因而导致泄漏只出现在生产中。在q种情况下,需要用一些开销较低的工h监控和查扑ֆ存泄漏。还需要能够无需重启pȝ或修改代码就可以这些工兯接到正在q行的系l上。可能最重要的是Q当q行分析Ӟ需要能够断开工具而保持系l不受干扰?/font>

  虽然OutOfMemoryError通常都是内存泄漏的信P但是也有可能应用E序实正在使用q么多的内存;对于后者,或者必d加JVM可用的堆的数量,或者对应用E序q行某种更改Q它用较的内存。但是,在许多情况下QOutOfMemoryError都是内存泄漏的信受一U查明方法是不间断地监控GC的活动,定内存使用量是否随着旉增加。如果确实如此,可能发生了内存泄漏?/font>



]]>
Java中equals() hashcode()Ҏhttp://www.tkk7.com/byrtiger/archive/2008/08/04/219919.htmlq风舞?/dc:creator>q风舞?/author>Mon, 04 Aug 2008 06:38:00 GMThttp://www.tkk7.com/byrtiger/archive/2008/08/04/219919.htmlhttp://www.tkk7.com/byrtiger/comments/219919.htmlhttp://www.tkk7.com/byrtiger/archive/2008/08/04/219919.html#Feedback0http://www.tkk7.com/byrtiger/comments/commentRss/219919.htmlhttp://www.tkk7.com/byrtiger/services/trackbacks/219919.html      Java语言中的equals的规范:

          1Q?/font> 自反性:对于M一个非I引?/span>xQ?/span>x.equals(x)应该q回trueQ?br />     2Q?/font> 对称性:对于M引用x?/span>yQ如?/span>x.equals(y)q回trueQ那?/span>y.equals(x)也应该返?/span>true?br />     3Q?/font> 传递性:对于M引用x?/span>y?/span>zQ如?/span>x.equals(y)q回trueQ?/span>y.equals(z)q回trueQ那?/span>x.equals(z)也应该返?/span>true?br />     4Q?/font> 一致性:如果x?/span>y引用的对象没有发生变化,那么反复调用x.equals(y)应该q回同样的结果?br />     5Q?/font> 对于M非空引用xQ?/span>x.equals(null)应该q回false?br />
 public boolean equals(Object obj) {
  boolean result = false;
  if (this == obj)
   return true;
  if (!(obj instanceof Student))
   return false;
  Student objTemp = (Student) obj;
  if (this.getId() == objTemp.getId())
   result = true;
  return result;
 }

Java语言中的hashcodeQ?/span>

  1. 一个非0常数Q例?7Q储存于int result变量中?br />   2. 对对象中的每一个有意义的字DfQ更切地说是被equals()所考虑的每一个字D)q行如下处理Q?br />     A. 对这个字D计出型别为int的hash ?cQ?br />       i. 如果字段是个booleanQ计?f ? 0 : 1)?br />       ii. 如果字段是个byte,char,short或intQ计?int)f?br />       iii. 如果字段是个longQ计?int)(f^(f >>> 32))?br />       iv. 如果字段是个floatQ计Float.floatToIntBits(f)?br />       v. 如果字段是个doubleQ计Double.doubleToLongBits(f)Q然后将计算l果按步?.A.iii处理?br />       vi. 如果字段是个object referenceQ而且class 的equals()透过「递归呼叫equals()」的方式来比较这一字段Q那么就同样也对该字D递归呼叫hashCode()?br />       vii. 如果字段是个arrayQ请每个元素视为独立字Dc也是说对每一个有意义的元素施行上q规则,用以计算出hash 码,然后再依步骤2.B这些数值组合v来?br />     B. 步骤A计算出来的hash?c按下列公式组合到变量result中:result = 37*result + c;
 3. 传回result?br />  4. 完成hashCode()之后Q反w自省一下:是否相等的实体具有相{的hash 码?如果不是Q找出原因ƈ修正问题?/span>



]]>
转蝲QJava标准cd提供的容器ȝhttp://www.tkk7.com/byrtiger/archive/2008/07/03/212296.htmlq风舞?/dc:creator>q风舞?/author>Thu, 03 Jul 2008 04:11:00 GMThttp://www.tkk7.com/byrtiger/archive/2008/07/03/212296.htmlhttp://www.tkk7.com/byrtiger/comments/212296.htmlhttp://www.tkk7.com/byrtiger/archive/2008/07/03/212296.html#Feedback0http://www.tkk7.com/byrtiger/comments/commentRss/212296.htmlhttp://www.tkk7.com/byrtiger/services/trackbacks/212296.html Java标准cd提供的容器ȝ

在Java中,容器主要包括Q数l?Array)、集?Collection)和映?Map)三种?br />
(1)数组ArrayQ将数字与元素联pv来,其中的元素都h相同的数据类型,只能通过下标来访问其元素Q数l可以是一l的Q也可以是多l的Q数l一? 生成Q其定w׃能改变。数l是一U复合数据类型,在Java中,除了可以?#8220;int[] array;”来声明和表示一个数l,q可以用ArraycL表示一个数l,同样圎ͼJDKcdq提供了Arrayscȝ操作数组Q该cd义了Ҏl进? 操作的各U方?赋倹{排序、搜索、比较、查扑օ素等)?br />
(2)集合CollectionQ是一个接口类Q包括List、Set、Queue{子接口Q其具体的实现类可以用来保存多个元素。这里只讨论常用的子? 口List和Set的常用实现类。常用的List实现cLArrayList、Vector和LinkedList{,常用的Set实现cL HashSet、LinkedHashSet和TreeSet{。需要注意的是,List和Set有着很大的不同,主要包括是否允许元素重复和是否维护元 素的ơ序?br />
(3)映射MapQ保存相兌的键值对。其具体的实现类可以键映射到|Ҏ键得到|因此Q一个映不能包含重复的键,但是允许有重复的|每个键最 多只能映到一个倹{?常见的Map实现cLHashMap、Hashtable、LinkedHashMap和TreeMap{?br />
Z讨论的方便,下面以ArrayQList、Set、Map为分cL讨论q几U容器的使用特点?br />
(1)ArrayQ?br />
    数组的用很直接Q主要是Ҏ下表 来获取其元素。其特点是一旦生成,其容量不能改变,q且每个元素之间不允许有“I隙”。其使用实例可以参考电子工业出版社“宝典”pd之《Java JDK 实例宝典?夏先? ~著)Q个人感觉这本书写得不错Q给Z许多JDKcd的具体用实例,代码的注释也比较详细Q很适合初学者入门学习用,如果看Java Doc q是有不明白的地方,也可以参考此?)

(2)ListQ可用来存放多个元素Q能够自动扩充容量,能够l护元素的次序,q且允许元素重复?br />
    (2.1)ArrayListc:最常用的List实现c,内部是通过数组实现的,它允许对元素q行快速的随机讉KQ但是要从ArrayList 的中间位|插入或者删?nbsp;   元素Ӟ需要对数组q行复制、移动,代h比较高,因此QArrayList适合随机查找和遍历,不适合插入和删除?br />
    (2.2)Vectorc:同ArrayList一P其内部也是通过数组实现的,不同的是QVector支持U程的同步,能够避免多线E同时写而引L不一_但是实现U程的同步需要很高的代hQ因此访问Vector比ArrayList慢?br />
    (2.3)LinkedListc:见其名,该类与链表肯定有关系:)该类的内部是通过链表来实现的Q很适合数据的动态插入和删除Q但是随卌? 和遍历的速度比较慢。此外,该类q提供了List接口中没有定义的ҎQ专门用于操作表头和表尾元素Q可以当作堆栈、队列和双向队列使用?/span>

(3)SetQ可用来存放多个元素Q但是不允许元素重复(即不保存重复元素)Q也不能够维护元素的ơ序。很直观Q联想一下数学中的集合的概念很好理解了。此外,需要注意的是,加入Set的元素必d义equals()Ҏ以确保对象的唯一性,如String对象?br />
    (3.1) HashSetc:采用散列函数对元素进行排序,是专门ؓ快速查询而设计的存入HashSet的对象必d义hashCode()Ҏ?br />
    (3.2)TreeSetc:采用U黑树的数据l构q行排序元素Q用它可以从Set中提取有序的序列?br />
    (3.3) LinkedHashSetc:内部使用散列以加快查询速度Q同时用链表维护元素的插入ơ序Q在使用q代器遍历时Q会按插入次序显C结果?br />

(4)MapQ可以用来存攄兌的键值对Q根据键得到倹{常见的Map实现cLHashMap、Hashtable、LinkedHashMap和TreeMap?/p>

    (4.1)HashMapc:一个最常用的MapQ它Ҏ键的hashCode值存储数据,Ҏ键可以直接获取它的|h很快的访问速度Q但不支持线E同步。HashMap最多允怸条记录的键ؓnullQ但是允许多条记录的gؓnull?br />     
    (4.2)Hashtablec:与HashMapcMQ但是它不允许记录的键或者gؓnullQ支持线E同步,因而Hashtable在写入数据时会很慢?br />
    (4.3)LinkedHashMapc:保存了记录的插入序Q在用Iterator遍历它时Q先得到的记录肯定时先插入的Q在遍历的时候比HashMap慢?br />
    (4.4)TreeMapc:能够把它保存的记录根据键排序Q默认ؓ升序排列。当用Iterator遍历它时Q得到的记录是排q序的记录?/p>

]]>
վ֩ģ壺 91Ƶַ| aëƬƵ| jizzjizz߲| AVר4SE| һŮëƬ| AҹƬƷվ| AV㽶һ| ëƬѹۿַ| ձۺϸ| ɫƬѹۿ| ޾ƷӰ| ձƬ߿a| þ޾Ʒ11p| ޹Ʒ˰| һĻ| һ| ѾƷһ35| ޹Ʒһ| ߹ۿƬaѹۿ | һ| ޸Ů侫| һһëƬȫ| þƵһ| ˳ߵӰ| ҹƵվ| þۺɫhezyo| ĻŮһ| ˵Ӱѹۿ| ŷպۺ| øѹۿ| Ļavר| ޵һƷӰ| ձһ| ĻѲƵ| ɫavɫ߹| պשר2020| ĻѾþ9һ9| ޸Ƶַ| ŷƷպһҹҹ | ëƬ߲ѹۿ| ŷͽȺ|