??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲精品国产日韩无码AV永久免费网,亚洲午夜福利在线观看,亚洲欧洲日产国产综合网http://www.tkk7.com/anwenhao/zh-cnSat, 10 May 2025 11:02:06 GMTSat, 10 May 2025 11:02:06 GMT60JDO 的用和集成http://www.tkk7.com/anwenhao/archive/2011/05/15/350280.html安文?/dc:creator>安文?/author>Sun, 15 May 2011 09:19:00 GMThttp://www.tkk7.com/anwenhao/archive/2011/05/15/350280.htmlhttp://www.tkk7.com/anwenhao/comments/350280.htmlhttp://www.tkk7.com/anwenhao/archive/2011/05/15/350280.html#Feedback0http://www.tkk7.com/anwenhao/comments/commentRss/350280.htmlhttp://www.tkk7.com/anwenhao/services/trackbacks/350280.htmlJDO 的用和集成
     q里不想讨论JDO和JPA的区别,也不讨论JDO的规范,单只是从JDO的用和与应用的集成角度来概q?br />
1. 下蝲JDO规范的实现开源包。目前主的JDO实现有:(x)
*.TJDO http://tjdo.sf.net
*.Speedo http://speedo.objectweb.org
*.JORM http://jorm.objectweb.org
*.XORM http://xorm.sourceforge.net
*.JPOX http://jpox.sourceforge.net
*.OJB http://db.apache.org/ojb/
*.DataNucleus http://www.datanucleus.org/
 
2. q里选择DataNucleus为JDO的实玎ͼ因ؓ(f)个h认ؓ(f)datanucleus大有一lO/R Mapping天下的架ѝ前端支持JDO/JPA规范Q后面能接多U数据存储^?RDBMS, ODBMS, Map-based, Web-based, documents, etc) . q且直接可与bigtable、hbase{分布式数据库集成。实在强大?br />      * 下蝲DataNucleusE序?br />      * 下蝲DataNucleus在eclipse下的扩展插g

3. 如果使用dataNucleusq接DBMS数据?Mysql)需要加入以下几个jar包:(x)
     datanucleus-enhancer-3.0.0-m4.jar   jdo-api-3.1-SNAPSHOT-20110319.jar  datanucleus-api-jdo-3.0.0-m4.jar  datanucleus-jdo-query-3.0.0-m2.jar    asm.jar
     mysql-connector-java-5.0.4-bin.jar  datanucleus-cache-3.0.0-m2.jar    datanucleus-management-1.0.2.jar datanucleus-core-3.0.0-m4.jar     datanucleus-rdbms-3.0.0-m4.jar

4. 创徏一个entity class q|映文?如下Q?br />      entity class :
@PersistenceCapable
public class Person {     
       @PrimaryKey
       private String name ;
       private int age ;
       private String mail ;
     .......
}
   mapping xml
<jdo>
    <package name="com.jdo.data.nucleus.model">
        <class name="Person">
            <field name="name" persistence-modifier="persistent">
                 <column length="100" />
            </field>
            <field name="age" persistence-modifier="persistent"/>
            <field name="mail" persistence-modifier="persistent"/>
        </class>
    </package>
</jdo>

5.创徏JDO操作c:(x)
             Map<String,String> JDOConfig = new HashMap<String,String>();
            JDOConfig.put( "javax.jdo.PersistenceManagerFactoryClass" ,"org.datanucleus.api.jdo.JDOPersistenceManagerFactory" );
           
            JDOConfig.put("javax.jdo.option.ConnectionURL", "jdbc:mysql://localhost/acegi" );
            JDOConfig.put( "javax.jdo.option.ConnectionDriverName" , "com.mysql.jdbc.Driver" );
            JDOConfig.put( "javax.jdo.option.ConnectionUserName" , "root");
            JDOConfig.put( "javax.jdo.option.ConnectionPassword" , "root");
            JDOConfig.put( "javax.jdo.option.NontransactionalRead" , "true");
            JDOConfig.put( "javax.jdo.option.NontransactionalWrite" , "true");
            JDOConfig.put( "datanucleus.autoCreateSchema" , "true" );
           
            PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(JDOConfig);
            PersistenceManager pm = pmf.getPersistenceManager();
            Person person = null;
            System. out.println("Insert iterm into DB. " );
             //insert
            person = new Person("wenhao" ,123,"wenhao@gmail.com");
            pm.makePersistent(person);
             //select
             getPersonsFromDB(pm);
             //update
            person.setMail( "wenhao@sina.com.cn");
            pm.close();
           
            person.setAge(1000);
            System. out.println("instance level : " + person.getAge());
           
            pmf = JDOHelper. getPersistenceManagerFactory(JDOConfig);
            pm = pmf.getPersistenceManager();
            List<Person> updatePersons = getPersonsFromDB(pm);
             if(updatePersons != null && updatePersons.size() > 0) {
                   for(Person updatePerson : updatePersons)
                         //delete
                        pm.deletePersistent(updatePerson);
                  System. out.println("Delete iterms from DB." );
            }
            pm.close();
            //select
            Query q = pm.newQuery( "SELECT FROM " + Person.class.getName() + " WHERE name == 'wenhao'" );
            List<Person> updatePersons = (List)q.execute();

6. q行JDO操作c,q时直接q行?x)报如下的错误?x)
This means that it either hasnt been enhanced, or that the enhanced version of the file is not in the CLASSPATH (or is hidden by an unenhanced version), or the Meta-Data/annotations for the class are not found
     q个错误的是因ؓ(f)没有对Entity classq行jdo的enhance来增强entity的二q制代码。故需要在project上增加datanucleus支持。ƈq行enhancer tool来enhance entity。运行后可通过反编译工h查看transform后的class。可发现多了一些属性和Ҏ(gu)。这些都是对JDO entity的扩展?br />
7.正常q行
     ?x)发现在person.setMail( "wenhao@sina.com.cn" );?x)更改到底层的数据库中,而person.setAge(1000);q不?x)更?gu)据库字段。其实很Ҏ(gu)理解。类似hibernate的entity的几个状态,自由?#183;持久?#183;游离态?当pm.close();后person处于自由态,修改的属性只有在instance内部有效。而在pm cloase或transaction.commit之前Ӟentity仍处理持久化状态,直接修改属性,?x)持久化到底层数据库中?br />     
8.JDO对象的多对多关系实现。多对多和hibernate的配|类|主要q是在配|文件上做一些配|。配|文件如下:(x)
Person.jdo:
<jdo>
    <package name="com.jdo.data.nucleus.model">
        <class name="Person">
            <field name="name" persistence-modifier="persistent">
                  <column length="100" jdbc-type="VARCHAR" />
            </field>
            <field name="age" persistence-modifier="persistent"/>
            <field name="mail" persistence-modifier="persistent"/>
            <field name="roles" persistence-modifier="persistent" table="PERSON_RULE">
                  <collection element-type="com.jdo.data.nucleus.model.Role" />
                  <join>
                    <column name="name" />
                </join>
                <element>
                    <column name="roleName" />
                </element>
            </field>

        </class>
    </package>
</jdo>
Role.jdo:
<jdo>
    <package name="com.jdo.data.nucleus.model">
        <class name="Role">
            <field name="roleName" persistence-modifier="persistent">
                  <column length="100" jdbc-type="VARCHAR" />
            </field>
            <field name="roleDesc" persistence-modifier="persistent"/>
            <field name="persons" persistence-modifier="persistent" table="PERSON_RULE">
                  <collection element-type="com.jdo.data.nucleus.model.Person" />
                  <join>
                    <column name="roleName" />
                </join>
                <element>
                    <column name="name" />
                </element>
            </field>

        </class>
    </package>
</jdo>
Person.java:
@PersistenceCapable
public class Person {
       @PrimaryKey
       private String name ;
       private int age ;
       private String mail ;     
       @Element
       private Set<Role> roles ;
}
Role.java:
@PersistenceCapable
public class Role {
       @PrimaryKey
       private String roleName ;
       private String roleDesc ;
       @Element
       private Set<Person> persons ;
}
以上配置可实现多对多的关pRƈ能够q行兌查询?br />


]]>
l大家推荐一ƾ超L(fng)软g原型设计工具-Balsamiq Mockupshttp://www.tkk7.com/anwenhao/archive/2009/02/25/256600.html安文?/dc:creator>安文?/author>Wed, 25 Feb 2009 06:02:00 GMThttp://www.tkk7.com/anwenhao/archive/2009/02/25/256600.htmlhttp://www.tkk7.com/anwenhao/comments/256600.htmlhttp://www.tkk7.com/anwenhao/archive/2009/02/25/256600.html#Feedback6http://www.tkk7.com/anwenhao/comments/commentRss/256600.htmlhttp://www.tkk7.com/anwenhao/services/trackbacks/256600.html做Y件品设计时l常?x)涉及(qing)到原型设计Q用U笔dU,用Visiod劌Ӏ而且今年产品要做大的调整与换代,原型设计更ؓ(f)手Q决定花力气找一Ƒ־心应手的原型设计工具Q? Balsamiq Mockups 让我眼前一亮!q不急待Q进行了一dU试用,呵!对于软g原型构造来_(d)可真?#8220;随心所ƌӀ信手拈?#8221;Q中肯的说比U和W更为方ѝ?/p>

?/p>

|址Q?http://www.balsamiq.com/ 

在线演示地址Q?http://www.balsamiq.com/products/mockups

试用|址Q?http://www.balsamiq.com/demos/mockups/Mockups.html

整体截图Q?/p>

  mockupstour.jpg

功能和亮点:(x)

  1. 操作斚wQ拖拽,控g分组Q甚臛_素之间的寚w都做得很CQ?
  2. 预制了六十多个界面元素,从简单的输入框,下拉框,到经常用得到的导航条Q日历,表格Q到复杂的Tag CloudQCover Flow, 地图QW(xu)YSWYG的格式工h{,有了q些不用从头画vQ其实比用白杉K快;
  3. 界面元素的修改很单,比如D条的几个标签늚labelQ就是用逗号分隔的文字,下拉框的选项是分行的文字;
  4. 使用xml语言来记录和保存界面元素和布局Q从而其能够快速的导入C所需的Q何一个项目中Q或其他工具中?
  5. 可以设计导出成PNG格式的图片;
  6. 随着使用的熟l,快捷键便z上用场Q超q一半的元素均有快捷方式Q这更有助于原型的快速构造,几乎几分钟便可实C个满意的而复杂的原型设计Q?
  7. 跨^収ͼBalsamiq Mokups是用Flex和Air实现的,所以在Mac OS, Linux和W(xu)indows下都能用;
  8. 不仅仅有桌面版本Q还有能集成在ConfluenceQJIRAQ和XWiki中的版本Q得异地在U协作更方便有效Q?

   tour_controls.jpg

  3179518234_47b7d81a11.jpg


q么好的一ƾY件是不是免费的呢Q当然不是,但是软g的作者有N多种方式让你得到free license 的方法?br />

To get a free license key, you can do one of the following:

  • If your company bought Mockups for Confluence, JIRA or XWiki, ask your IT admin for your company's license information and use it FREE of charge.
  • If you are a do-gooder of any sort (non-profit, charity, open-source contributor, you get the idea), email Mariah with a short blurb and she'll send you a license, FREE of charge.
  • If you are a blogger / journalist / maven willing to write us up (honest reviews are the most useful to us) email Mariah a short blurb with the link to your blog and she'll send you a license, FREE of charge, so that you can evaluate Mockups properly.
  • If you are willing to demo Mockups to an audience of at least 15 people (at a user group, a conference, a BarCamp), email Mariah your info and she'll give you two licenses, one for you to keep and one to give away at the event, FREE of charge.
  • If you teach a high-school class, email Mariah the name of your school and your class, plus the number of students in your class. Mariah will send you a license for all of them.
  • A note to university students and professors: we currently do not offer free licenses to universities, but we'll be happy to offer you an additional 50% off any orders of 10 or more licenses. Let us know if you're interested and we'll set up a discount code for you.


你做C上的M一条。你可以得到免费的许可证了?br /> 嘿嘿Q终于暴露目的了…… 不过q么好的软gQ不推荐一下也实在说不q去?



]]>
RAIDb的理?/title><link>http://www.tkk7.com/anwenhao/archive/2008/12/10/245569.html</link><dc:creator>安文?/dc:creator><author>安文?/author><pubDate>Wed, 10 Dec 2008 13:35:00 GMT</pubDate><guid>http://www.tkk7.com/anwenhao/archive/2008/12/10/245569.html</guid><wfw:comment>http://www.tkk7.com/anwenhao/comments/245569.html</wfw:comment><comments>http://www.tkk7.com/anwenhao/archive/2008/12/10/245569.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.tkk7.com/anwenhao/comments/commentRss/245569.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/anwenhao/services/trackbacks/245569.html</trackback:ping><description><![CDATA[  <p style="text-align: left" align="left"><span style="font-family: 宋体">RAIDb</span><span style="font-family: 宋体">的目标:(x)</span></p> <p style="text-align: left" align="left"><span style="font-family: 宋体">通过多个廉L(fng)数据库实例组合到一个数据库阵列Q提供比单台数据库更好的性能和容错性?/span></p> <p style="text-align: left" align="left"><span style="font-family: 宋体">隐藏分布式数据库的复杂性,提供l数据库客户端一个独立的数据库?/span></p> <p style="text-align: left" align="left"><span style="font-family: 宋体">在RAIDb中,一个控制器在其他资源的前面。客户发送他们的h到RAIDb控制器,q个控制器将他们分发l一lRDBMS后端?/span></p> <p style="text-align: left" align="left"><span style="font-family: 宋体">有不同的RAIDbU别或数据分发方案可用,它提供不同的费用Q性能Q或者容错权衡?/span></p> <p style="text-align: left" align="left"><strong><span style="font-family: 宋体">全分?RAIDb-0)</span></strong></p> <p style="text-align: left" align="left"><span style="font-family: 宋体">RAIDb-0 </span><span style="font-family: 宋体">分割数据库表C个数据库后端节点集?/span></p> <ul type="disc"> <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-family: 宋体">一个表本n不能再分割了。但是不同的表可以分布在不同的后端节点上?/span></li> <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-family: 宋体">RAIDb-0 </span><span style="font-family: 宋体">需要至两个数据库后端?/span></li> <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-family: 宋体">RAIDb-0 </span><span style="font-family: 宋体">当前只能和一个控制器配置一起用?/span></li> <li style="color: red; text-align: left; tab-stops: list 36.0pt"><span style="font-family: 宋体">RAIDb-0 </span><span style="font-family: 宋体">提供了一定的性能扩展Q但不支持容错功能?/span></li> </ul> <p style="color: red; text-align: left; tab-stops: list 36.0pt"><span style="font-family: 宋体"><img height="261" alt="" src="http://www.tkk7.com/images/blogjava_net/anwenhao/raidb-0.JPG" width="509" border="0" /></span></p> <p style="text-align: left" align="left"><strong><span style="font-family: 宋体">注意Q?/span></strong></p> <p style="text-align: left" align="left"><em><span style="color: red; font-family: 宋体">当前的实C支持分布式join。也是说如果你惛_表t1和t2间进行join操作Q你必须保t1和t2在同一台机器上?/span></em></p> <p style="text-align: left" align="left"><span style="font-family: 宋体">扩展性的提升取决于表的数目和各个表的负蝲情况Q?/span></p> <ul type="disc"> <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-family: 宋体">如果你的数据库很大,没有单个节点有够的定w存放整个数据库,那么RAIDb-0允许你把一个数据库分布存储到到一l节点上?/span></li> <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-family: 宋体">此外Q每个数据库引擎处理一个小的数据集可以可能的提高~存利用率,因ؓ(f)Lh那几个表?/span></li> <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-family: 宋体">RAIDb-0</span><span style="font-family: 宋体">存储的用率是最高的Q因为没有重复的信息?/span></li> <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-family: 宋体">RAIDb-0</span><span style="font-family: 宋体">需要控制器知道那个表在哪台服务器上Q以便把h导向正确的节炏V因为没有重复的表,一直一个后端会(x)执行一个特定的h。这些信息也可以静态配|到配置文g中,也可以从每个数据库中抓取其schema来动态构建?/span></li> </ul> <p style="text-align: left" align="left"><strong><span style="font-family: 宋体">全复?(RAIDb-1)</span></strong></p> <ul type="disc"> <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-family: 宋体">RAIDb-1 </span><span style="font-family: 宋体">在一l后端上提供了一个数据库的全镜像?/span></li> <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-family: 宋体">RAIDb-1 </span><span style="font-family: 宋体">需要至两个后端节点,但是理论上后端的数量没有上限的限制。每个后端必L_的空间运行整个数据库?/span></li> <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-family: 宋体">RAIDb-1 </span><span style="font-family: 宋体">允许在集配|中使用几个控制器来为关键系l获得高可用性?/span></li> </ul> <p style="text-align: left; tab-stops: list 36.0pt"><span style="font-family: 宋体"><img height="252" alt="" src="http://www.tkk7.com/images/blogjava_net/anwenhao/raidb-1.JPG" width="527" border="0" /></span></p> <p style="text-align: left" align="left"><span style="font-family: 宋体">RAIDb-1</span><span style="font-family: 宋体">的扩展能力取决于控制器广播更新所有节点的能力。如果有大量后端数据库,使用复合RAIDb可以获得更好的扩展性?/span></p> <p style="text-align: left" align="left"><span style="color: red; font-family: 宋体">RAIDb-1</span><span style="color: red; font-family: 宋体">提供了对L询的加速,因ؓ(f)他们可以被均衡到所有后端上。另一斚wQ它对写操作没有加速(update,insert,deletehQ,因ؓ(f)他们必须q播到所有节炏V写操作在所有的后端q行执行?/span><span style="font-family: 宋体">所以,在写的角度来看,RAIDb-1可能比不上一个单独的节点Q但是从ȝ角度来看Q性能?x)随着后端节点的增加而线性增ѝ?/span></p> <p style="text-align: left" align="left"><span style="font-family: 宋体">RAIDb-1</span><span style="font-family: 宋体">有很好的定w性,因ؓ(f)pȝ即只有一个后端可用时也可以保持工作?/span></p> <p style="text-align: left" align="left"><span style="font-family: 宋体">不像RAIDb-0QRAIDb-1控制器不需要知道数据库的结构,因ؓ(f)所有的节点都有能力处理Mh。然后,RAIDb-1提供了一个缓存,它需要数据库l构来维护缓存的一致性?/span></p> <p style="text-align: left" align="left"><strong><span style="font-family: 宋体">部分复制 (RAIDb-2)</span></strong></p> <p style="text-align: left" align="left"><span style="font-family: 宋体">RAIDb-2</span><span style="font-family: 宋体">可以看作是RAIDb-0 ?RAIDb-1权衡下的一个中庸的解决Ҏ(gu)。它支持调整每个数据库表的部分复制程度,以获得一个做好的d性能?/span></p> <p style="text-align: left" align="left"><span style="font-family: 宋体">RAIDb-2:</span></p> <ul type="disc"> <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-family: 宋体">要求臛_三个数据库后端;</span></li> <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-family: 宋体">要求每个数据库表在至两个后端上可用以解军_Ҏ(gu)障问题?/span></li> <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-family: 宋体">不要求Q何一个节点可以运行整个数据库?/span></li> </ul> <p style="text-align: left" align="left"><span style="font-family: 宋体">下面是RAIDb-2的典型应用:(x)<br /> </span></p> <p style="text-align: left" align="left"><span style="font-family: 宋体"><br /> <img height="251" alt="" src="http://www.tkk7.com/images/blogjava_net/anwenhao/raidb-2.JPG" width="504" border="0" /><br /> <br /> 没有或者只有少数几个节点运行整个数据库Q一l节点各自运行这数据库的一部分?/span></p> <p style="text-align: left" align="left"><span style="font-family: 宋体">下图中的例子昄了RAIDb-2的部分复Ӟ数据库包?个表Qx,y,和z.W一个后端包含整个数据库Q但是其他节炚w只包含一个或两个表。表x ?y?份拷?表z有两份拷贝。Q一节点p|Q仍然可以从其他的存?gu)z节点中扑ֈ数据?/span></p> <p style="text-align: left" align="left"><span style="color: red; font-family: 宋体">RAIDb-2</span><span style="color: red; font-family: 宋体">对于异构数据库非常有用。一个已有的企业数据库用商业数据库Q但是要建立一个全拯无论是从存储上还是从增加许可的费用上来说Q都太贵了。有了RAIDb-2好办了Q你可以增加几个型开源数据库来各自运行整个数据库中的某些部分来代替整个数据库Q这样也可以获得更好的容错性?/span></p> <p style="text-align: left" align="left"><span style="font-family: 宋体">RAIDb-2</span><span style="font-family: 宋体">定w性没有RAIDb-1好,但是它有效的改善了写操作的效率。跟RAIDb-0cMQRAIDb-2也要求控制器知道所有数据库的结构,以便请求定向到适当的节炏V?/span></p><img src ="http://www.tkk7.com/anwenhao/aggbug/245569.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/anwenhao/" target="_blank">安文?/a> 2008-12-10 21:35 <a href="http://www.tkk7.com/anwenhao/archive/2008/12/10/245569.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入介绍什么是java虚拟?/title><link>http://www.tkk7.com/anwenhao/archive/2008/01/13/174972.html</link><dc:creator>安文?/dc:creator><author>安文?/author><pubDate>Sun, 13 Jan 2008 05:37:00 GMT</pubDate><guid>http://www.tkk7.com/anwenhao/archive/2008/01/13/174972.html</guid><wfw:comment>http://www.tkk7.com/anwenhao/comments/174972.html</wfw:comment><comments>http://www.tkk7.com/anwenhao/archive/2008/01/13/174972.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/anwenhao/comments/commentRss/174972.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/anwenhao/services/trackbacks/174972.html</trackback:ping><description><![CDATA[<p>  </p> <p><span style="font-family: 宋体">一、什么是</span><a target="_blank"><span style="color: windowtext; text-decoration: none; text-underline: none">Java</a></span><span style="font-family: 宋体">虚拟?/span><br />      <span style="font-family: 宋体">当你谈到</span><a target="_blank"><span style="color: windowtext; text-decoration: none; text-underline: none">Java</a></span><span style="font-family: 宋体">虚拟机时Q你可能是指Q?/span><br />      1<span style="font-family: 宋体">、抽象的</span>Java<span style="font-family: 宋体">虚拟?/span><br />      2<span style="font-family: 宋体">、一个具体的</span>Java<span style="font-family: 宋体">虚拟机实?/span><br />      3<span style="font-family: 宋体">、一个运行的</span>Java<span style="font-family: 宋体">虚拟机实?/span><br /> <span style="font-family: 宋体">二?/span>Java<span style="font-family: 宋体">虚拟机的生命周期</span><br />      <span style="font-family: 宋体">一个运行中?/span>Java<span style="font-family: 宋体">虚拟机有着一个清晰的dQ执?/span>Java<span style="font-family: 宋体">E序。程序开始执行时他才q行Q程序结束时他就停止。你在同一台机器上q行三个E序Q就?x)有三个q行中的</span>Java<span style="font-family: 宋体">虚拟机?/span><br />      Java<span style="font-family: 宋体">虚拟机L开始于一?/span>main()<span style="font-family: 宋体">Ҏ(gu)Q这个方法必L公有、返?/span>void<span style="font-family: 宋体">、直接受一个字W串数组。在E序执行Ӟ你必ȝ</span>Java<span style="font-family: 宋体">虚拟机指明这个包?/span>main()<span style="font-family: 宋体">Ҏ(gu)的类名?/span><br />      Main()<span style="font-family: 宋体">Ҏ(gu)是程序的L(fng)Q他被执行的U程初始化ؓ(f)E序的初始线E。程序中其他的线E都׃来启动?/span>Java<span style="font-family: 宋体">中的U程分ؓ(f)两种Q守护线E?/span> <span style="font-family: 宋体">Q?/span>daemon<span style="font-family: 宋体">Q和普通线E(</span>non-daemon<span style="font-family: 宋体">Q。守护线E是</span>Java<span style="font-family: 宋体">虚拟׃用的U程Q比如负责垃圾收集的U程是一个守护线E。当Ӟ你也?/span> <span style="font-family: 宋体">以把自己的程序设|ؓ(f)守护U程。包?/span>Main()<span style="font-family: 宋体">Ҏ(gu)的初始线E不是守护线E?/span><br />      <span style="font-family: 宋体">只要</span>Java<span style="font-family: 宋体">虚拟Zq有普通的U程在执行,</span>Java<span style="font-family: 宋体">虚拟机就不会(x)停止。如果有_的权限,你可以调?/span>exit()<span style="font-family: 宋体">Ҏ(gu)l止E序?/span><br /> <span style="font-family: 宋体">三?/span>Java<span style="font-family: 宋体">虚拟机的体系l构</span><br />      <span style="font-family: 宋体">?/span>Java<span style="font-family: 宋体">虚拟机的规范中定义了一pd的子pȝ、内存区域、数据类型和使用指南。这些组件构成了</span>Java<span style="font-family: 宋体">虚拟机的内部l构Q他们不仅仅?/span>Java<span style="font-family: 宋体">虚拟机的实现提供了清晰的内部l构Q更是严D定了</span>Java<span style="font-family: 宋体">虚拟机实现的外部行ؓ(f)?/span> <br />      <span style="font-family: 宋体">每一?/span>Java<span style="font-family: 宋体">虚拟机都׃个类加蝲器子pȝQ?/span>class loader subsystem<span style="font-family: 宋体">Q,负责加蝲E序中的cdQ类和接口)Qƈ赋予唯一的名字。每一?/span>Java<span style="font-family: 宋体">虚拟机都有一个执行引擎(</span>execution engine<span style="font-family: 宋体">Q负责执行被加蝲cM包含的指令?/span><br />      <span style="font-family: 宋体">E序的执行需要一定的内存I间Q如字节码、被加蝲cȝ其他额外信息、程序中的对象、方法的参数、返回倹{本地变量、处理的中间变量{等?/span>Java<span style="font-family: 宋体">虚拟机将</span> <span style="font-family: 宋体">q些信息l统保存在数据区Q?/span>data areas<span style="font-family: 宋体">Q中。虽然每?/span>Java<span style="font-family: 宋体">虚拟机的实现中都包含数据区,但是</span>Java<span style="font-family: 宋体">虚拟范对数据区的规定却非常的抽象。许多结构上的细节部分都留给?/span> Java<span style="font-family: 宋体">虚拟机实现者自己发挥。不?/span>Java<span style="font-family: 宋体">虚拟机实C的内存结构千差万别。一部分实现可能占用很多内存Q而其他以下可能只占用很少的内存;一些实现可</span> <span style="font-family: 宋体">能会(x)使用虚拟内存Q而其他的则不使用。这U比较精炼的</span>Java<span style="font-family: 宋体">虚拟机内存规U,可以使得</span>Java<span style="font-family: 宋体">虚拟机可以在q泛的^C被实现?/span><br />      <span style="font-family: 宋体">数据Z的一部分是整个程序共有,其他部分被单独的U程控制。每一?/span>Java<span style="font-family: 宋体">虚拟机都包含Ҏ(gu)区(</span>method area<span style="font-family: 宋体">Q和堆(</span>heap<span style="font-family: 宋体">Q,他们都被整个E序׃n?/span>Java<span style="font-family: 宋体">虚拟机加载ƈ解析一个类以后Q将从类文g中解析出来的信息保存与方法区中。程序执行时创徏?/span> <span style="font-family: 宋体">对象都保存在堆中?/span> <br />      <span style="font-family: 宋体">当一个线E被创徏Ӟ?x)被分配只属于他自己?/span>PC<span style="font-family: 宋体">寄存?/span>“pc register”<span style="font-family: 宋体">Q程序计数器Q和</span>Java<span style="font-family: 宋体">堆栈Q?/span>Java stack<span style="font-family: 宋体">Q。当U程不掉用本地方法时Q?/span>PC<span style="font-family: 宋体">寄存器中保存U程执行的下一条指令?/span>Java<span style="font-family: 宋体">堆栈保存了一个线E调用方法时的状态,包括本地变量、调用方法的</span> <span style="font-family: 宋体">参数、返回倹{处理的中间变量。调用本地方法时的状态保存在本地Ҏ(gu)堆栈中(</span>native method stacks<span style="font-family: 宋体">Q,可能再寄存器或者其他非q_独立的内存中?/span><br />      Java<span style="font-family: 宋体">堆栈有堆栈块Q?/span>stack frames (or frames)<span style="font-family: 宋体">Q组成。堆栈块包含</span>Java<span style="font-family: 宋体">Ҏ(gu)调用的状态。当一个线E调用一个方法时Q?/span>Java<span style="font-family: 宋体">虚拟Z(x)一个新的块压到</span>Java<span style="font-family: 宋体">堆栈中,当这个方法运行结束时Q?/span>Java<span style="font-family: 宋体">虚拟Z(x)对应的块弹出ƈ抛弃?/span><br />      Java<span style="font-family: 宋体">虚拟Z使用寄存器保存计的中间l果Q而是?/span>Java<span style="font-family: 宋体">堆栈在存放中间结果。这是的</span>Java<span style="font-family: 宋体">虚拟机的指o(h)更紧凑,也更Ҏ(gu)在一个没有寄存器的设备上实现</span>Java<span style="font-family: 宋体">虚拟机?/span> <br />      <span style="font-family: 宋体">图中?/span>Java<span style="font-family: 宋体">堆栈中向下增长的Q?/span>PC<span style="font-family: 宋体">寄存器中U程三ؓ(f)灰色Q是因ؓ(f)它正在执行本地方法,他的下一条执行指令不保存?/span>PC<span style="font-family: 宋体">寄存器中?/span><br /> <span style="font-family: 宋体">四、数据类型(</span>Data Types<span style="font-family: 宋体">Q?/span><br />      <span style="font-family: 宋体">所?/span>Java<span style="font-family: 宋体">虚拟Z使用的数据都有确定的数据cdQ数据类型和操作都在</span>Java<span style="font-family: 宋体">虚拟范中严格定义?/span>Java<span style="font-family: 宋体">中的数据cd分ؓ(f)原始数据cd</span> <span style="font-family: 宋体">Q?/span>primitive types<span style="font-family: 宋体">Q和引用数据cdQ?/span>reference type<span style="font-family: 宋体">Q。引用类型依赖于实际的对象,但不是对象本w。原始数据类型不依赖于Q何东西,他们是本n表示的数据?/span><br /> <span style="font-family: 宋体">所?/span>Java<span style="font-family: 宋体">E序语言中的原始</span> <span style="font-family: 宋体">数据cdQ都?/span>Java<span style="font-family: 宋体">虚拟机的原始数据cdQ除了布?yu)(dng)型Q?/span>boolean<span style="font-family: 宋体">Q。当~译器将</span>Java<span style="font-family: 宋体">源代码编译ؓ(f)自己码时Q用整型(</span>int<span style="font-family: 宋体">Q或者字节型</span> <span style="font-family: 宋体">Q?/span>byte<span style="font-family: 宋体">Q去表示布尔型。在</span>Java<span style="font-family: 宋体">虚拟Z使用整数</span>0<span style="font-family: 宋体">表示布尔型的</span>false<span style="font-family: 宋体">Q用非零整数表C布?yu)(dng)型?/span>true<span style="font-family: 宋体">Q布?yu)(dng)数l被表示为字节数l,虽然?/span> <span style="font-family: 宋体">们可能会(x)以字节数l或者字节块Q?/span>bit fields<span style="font-family: 宋体">Q保存在堆中?/span><br />      <span style="font-family: 宋体">除了布尔型,其他</span>Java<span style="font-family: 宋体">语言中的原始cd都是</span>Java<span style="font-family: 宋体">虚拟Z的数据类型。在</span>Java<span style="font-family: 宋体">中数据类型被分ؓ(f)Q整形的</span>byte<span style="font-family: 宋体">Q?/span>short<span style="font-family: 宋体">Q?/span>int<span style="font-family: 宋体">Q?/span>long<span style="font-family: 宋体">Q?/span>char<span style="font-family: 宋体">和Q点型?/span>float<span style="font-family: 宋体">Q?/span>double<span style="font-family: 宋体">?/span>Java<span style="font-family: 宋体">语言中的数据cd在Q何主Z都有同样的范围?/span> <br />      <span style="font-family: 宋体">?/span>Java<span style="font-family: 宋体">虚拟Zq存在一?/span>Java<span style="font-family: 宋体">语言中不能用的原始数据cdq回值类型(</span>returnValue<span style="font-family: 宋体">Q。这U类型被用来实现</span>Java<span style="font-family: 宋体">E序中的</span>“finally clauses”<span style="font-family: 宋体">Q具体的参见</span>18<span style="font-family: 宋体">章的</span>“Finally Clauses”<span style="font-family: 宋体">?/span><br />      <span style="font-family: 宋体">引用cd可能被创Zؓ(f)Q类cdQ?/span>class type<span style="font-family: 宋体">Q,接口cdQ?/span>interface type<span style="font-family: 宋体">Q,数组cdQ?/span>array type<span style="font-family: 宋体">Q。他们都引用被动态创建的对象。当引用cd引用</span>null<span style="font-family: 宋体">Ӟ说明没有引用M对象?/span><br />      Java<span style="font-family: 宋体">虚拟范只定义了每一U数据类型表C的范围Q没有定义在</span><a target="_blank"><span style="color: windowtext; font-family: 宋体; text-decoration: none; text-underline: none">存储</a></span><span style="font-family: 宋体">时每U类型占用的I间。他们如?/span><a target="_blank"><span style="color: windowtext; font-family: 宋体; text-decoration: none; text-underline: none">存储</a></span><span style="font-family: 宋体">?/span>Java<span style="font-family: 宋体">虚拟机的实现者自己决定。关于Q点型更多信息参见</span>14<span style="font-family: 宋体">?/span>“Floating Point Arithmetic”<span style="font-family: 宋体">?/span> </p> <p>TypeRange<br /> byte8-bit signed two's complement integer (-27 to 27 - 1, inclusive)<br /> short16-bit signed two's complement integer (-215 to 215 - 1, inclusive)<br /> int32-bit signed two's complement integer (-231 to 231 - 1, inclusive)<br /> long64-bit signed two's complement integer (-263 to 263 - 1, inclusive)<br /> char16-bit unsigned Unicode character (0 to 216 - 1, inclusive)<br /> float32-bit IEEE 754 single-precision float<br /> double64-bit IEEE 754 double-precision float<br /> returnValueaddress of an opcode within the same method<br /> referencereference to an object on the heap, or null</p> <p><span style="font-family: 宋体">五、字节长?/span><br />      Java<span style="font-family: 宋体">虚拟Z最的数据单元式字Q?/span>word<span style="font-family: 宋体">Q,其大由</span>Java<span style="font-family: 宋体">虚拟机的实现者定义。但是一个字的大必够容U?/span>byte<span style="font-family: 宋体">Q?/span>short<span style="font-family: 宋体">Q?/span>int<span style="font-family: 宋体">Q?/span> char<span style="font-family: 宋体">Q?/span>float<span style="font-family: 宋体">Q?/span>returnValue<span style="font-family: 宋体">Q?/span>reference<span style="font-family: 宋体">Q两个字必须_容纳</span>long<span style="font-family: 宋体">Q?/span>double<span style="font-family: 宋体">。所以虚拟机的实现者至提供的字不能小</span> <span style="font-family: 宋体">?/span>31bits<span style="font-family: 宋体">的字Q但是最好选择特定q_上最有效率的字长?/span><br />      <span style="font-family: 宋体">在运行时Q?/span>Java<span style="font-family: 宋体">E序不能军_所q行机器的字ѝ字长也不会(x)影响E序的行为,他只是在</span>Java<span style="font-family: 宋体">虚拟Z的一U表现方式?/span><br /> <span style="font-family: 宋体">六、类加蝲器子pȝ</span><br />      Java<span style="font-family: 宋体">虚拟Z的类加蝲器分ZU:(x)原始cd载器Q?/span>primordial class loader<span style="font-family: 宋体">Q和cd载器对象Q?/span>class loader objects<span style="font-family: 宋体">Q。原始类加蝲器是</span>Java<span style="font-family: 宋体">虚拟机实现的一部分Q类加蝲器对象是q行中的E序的一部分。不同类加蝲器加载的c被不同的命名空间所分割?/span><br />      <span style="font-family: 宋体">cd载器调用了许?/span>Java<span style="font-family: 宋体">虚拟Z其他的部分和</span>java.lang<span style="font-family: 宋体">包中的很多类。比如,cd载对象就?/span>java.lang.ClassLoader<span style="font-family: 宋体">子类</span> <span style="font-family: 宋体">的实例,</span>ClassLoader<span style="font-family: 宋体">cM的方法可以访问虚拟机中的cd载机Ӟ每一个被</span>Java<span style="font-family: 宋体">虚拟机加载的c都?x)被表示Z?/span> java.lang.Class<span style="font-family: 宋体">cȝ实例。像其他对象一Pcd载器对象?/span>Class<span style="font-family: 宋体">对象都保存在堆中Q被加蝲的信息被保存在方法区中?/span><br />      1<span style="font-family: 宋体">、加载、连接、初始化Q?/span>Loading, Linking and Initialization<span style="font-family: 宋体">Q?/span><br /> <span style="font-family: 宋体">cd载子pȝ不仅仅负责定位ƈ加蝲cLӞ他按照以下严格的步骤作了很多其他的事情:(x)Q具体的信息参见W七章的</span>“<span style="font-family: 宋体">cȝ生命周期</span>”<span style="font-family: 宋体">Q?/span><br />           1<span style="font-family: 宋体">Q、加载:(x)Lq导入指定类型(cd接口Q的二进制信?/span><br />           2<span style="font-family: 宋体">Q、连接:(x)q行验证、准备和解析</span><br />                <span style="font-family: 宋体">?/span><span style="font-family: 宋体">验证Q确保导入类型的正确?/span><br />                <span style="font-family: 宋体">?/span><span style="font-family: 宋体">准备Qؓ(f)cd分配内存q初始化为默认?/span><br />                <span style="font-family: 宋体">?/span><span style="font-family: 宋体">解析Q将字符引用解析为直接饮?/span><br />           3<span style="font-family: 宋体">Q、初始化Q调?/span>Java<span style="font-family: 宋体">代码Q初始化cd量ؓ(f)合适的?/span><br />      2<span style="font-family: 宋体">、原始类加蝲器(</span>The Primordial Class Loader<span style="font-family: 宋体">Q?/span><br />      <span style="font-family: 宋体">每个</span>Java<span style="font-family: 宋体">虚拟机都必须实现一个原始类加蝲器,他能够加载那些遵守类文g格式q且被信ȝcR但是,</span>Java<span style="font-family: 宋体">虚拟机的规范q没有定义如何加载类Q这?/span> Java<span style="font-family: 宋体">虚拟机实现者自己决定。对于给定类型名的类型,原始莱加载器必须扑ֈ那个cd名加</span>“.class”<span style="font-family: 宋体">的文件ƈ加蝲入虚拟机中?/span><br />      3<span style="font-family: 宋体">、类加蝲器对?/span><br />      <span style="font-family: 宋体">虽然cd载器对象?/span>Java<span style="font-family: 宋体">E序的一部分Q但?/span>ClassLoader<span style="font-family: 宋体">cM的三个方法可以访?/span>Java<span style="font-family: 宋体">虚拟Z的类加蝲子系l?/span><br />           1<span style="font-family: 宋体">Q?/span>protected final Class defineClass(…)<span style="font-family: 宋体">Q用这个方法可以出入一个字节数l,定义一个新的类型?/span><br />           2<span style="font-family: 宋体">Q?/span>protected Class findSystemClass(String name)<span style="font-family: 宋体">Q加载指定的c,如果已经加蝲Q就直接q回?/span><br />           3<span style="font-family: 宋体">Q?/span>protected final void resolveClass(Class c)<span style="font-family: 宋体">Q?/span>defineClass()<span style="font-family: 宋体">Ҏ(gu)只是加蝲一个类Q这个方法负责后l的动态连接和初始化?/span><br />      <span style="font-family: 宋体">具体的信息,参见W八?/span>“<span style="font-family: 宋体">q接模型</span>”<span style="font-family: 宋体">Q?/span> The Linking Model<span style="font-family: 宋体">Q?/span><br />      4<span style="font-family: 宋体">、命名空?/span><br />      <span style="font-family: 宋体">当多个类加蝲器加载了同一个类ӞZ保证他们名字的唯一性,需要在cd前加上加载该cȝcd载器的标识。具体的信息Q参见第八章</span>“<span style="font-family: 宋体">q接模型</span>”<span style="font-family: 宋体">Q?/span> The Linking Model<span style="font-family: 宋体">Q?/span><br /> <span style="font-family: 宋体">七、方法区Q?/span>The Method Area<span style="font-family: 宋体">Q?/span><br />      <span style="font-family: 宋体">?/span>Java<span style="font-family: 宋体">虚拟ZQ被加蝲cd的信息都保存在方法区中。这写信息在内存中的l织形式p拟机的实现者定义,比如Q虚拟机工作在一?/span>“little- endian”<span style="font-family: 宋体">的处理器上,他就可以信息保存ؓ(f)</span>“little-endian”<span style="font-family: 宋体">格式的,虽然?/span>Java<span style="font-family: 宋体">cL件中他们是以</span>“big-endian”<span style="font-family: 宋体">格式?/span> <span style="font-family: 宋体">存的。设计者可以用最适合q地机器的表C格式来存储数据Q以保证E序能够以最快的速度执行。但是,在一个只有很内存的讑֤上,虚拟机的实现者就不会(x)占用</span> <span style="font-family: 宋体">很大的内存?/span><br />      <span style="font-family: 宋体">E序中的所有线E共享一个方法区Q所以访问方法区信息的方法必LU程</span><a target="_blank"><span style="color: windowtext; font-family: 宋体; text-decoration: none; text-underline: none">安全</a></span><span style="font-family: 宋体">的。如果你有两个线E都d载一个叫</span>Lava<span style="font-family: 宋体">的类Q那只能׃个线E被容许d载这个类Q另一个必ȝ待?/span><br />      <span style="font-family: 宋体">在程序运行时Q方法区的大是可变的,E序在运行时可以扩展。有?/span>Java<span style="font-family: 宋体">虚拟机的实现也可以通过参数也订制方法区的初始大,最值和最大倹{?/span><br />      <span style="font-family: 宋体">Ҏ(gu)Z可以被垃圾收集。因为程序中的内q加蝲器动态加载,所有类可能变成没有被引用(</span>unreferenced<span style="font-family: 宋体">Q的状态。当cd成这U状态时Q他可</span> <span style="font-family: 宋体">能被垃圾攉掉。没有加载的cd括两U状态,一U是真正的没有加载,另一个种?/span>“unreferenced”<span style="font-family: 宋体">的状态。详l信息参见第七章的类的生命周?/span> <span style="font-family: 宋体">Q?/span>The Lifetime of a Class<span style="font-family: 宋体">Q?/span><br />      1<span style="font-family: 宋体">、类型信息(</span>Type Information<span style="font-family: 宋体">Q?/span><br />           <span style="font-family: 宋体">每一个被加蝲的类型,?/span>Java<span style="font-family: 宋体">虚拟Z都会(x)在方法区中保存如下信息:(x)</span><br />           1<span style="font-family: 宋体">Q、类型的全名Q?/span>The fully qualified name of the type<span style="font-family: 宋体">Q?/span><br />           2<span style="font-family: 宋体">Q、类型的父类型的全名Q除非没有父cdQ或者弗雷Ş?/span>java.lang.Object<span style="font-family: 宋体">Q(</span>The fully qualified name of the typeís direct superclass<span style="font-family: 宋体">Q?/span><br />           3<span style="font-family: 宋体">Q、给cd是一个类q是接口Q?/span>class or an interface<span style="font-family: 宋体">Q(</span>Whether or not the type is a class <span style="font-family: 宋体">Q?/span><br />           4<span style="font-family: 宋体">Q、类型的修饰W(</span>public<span style="font-family: 宋体">Q?/span>private<span style="font-family: 宋体">Q?/span>protected<span style="font-family: 宋体">Q?/span>static<span style="font-family: 宋体">Q?/span>final<span style="font-family: 宋体">Q?/span>volatile<span style="font-family: 宋体">Q?/span>transient<span style="font-family: 宋体">{)Q?/span>The typeís modifiers<span style="font-family: 宋体">Q?/span><br />           5<span style="font-family: 宋体">Q、所有父接口全名的列表(</span>An ordered list of the fully qualified names of any direct superinterfaces<span style="font-family: 宋体">Q?/span><br />           <span style="font-family: 宋体">cd全名保存的数据结构由虚拟机实现者定义。除此之外,</span>Java<span style="font-family: 宋体">虚拟要ؓ(f)每个cd保存如下信息Q?/span><br />           1<span style="font-family: 宋体">Q、类型的帔R池(</span>The constant pool for the type<span style="font-family: 宋体">Q?/span><br />           2<span style="font-family: 宋体">Q、类型字D늚信息Q?/span>Field information<span style="font-family: 宋体">Q?/span><br />           3<span style="font-family: 宋体">Q、类型方法的信息Q?/span>Method information<span style="font-family: 宋体">Q?/span><br />           4<span style="font-family: 宋体">Q、所有的静态类变量Q非帔RQ信息(</span>All class (static) variables declared in the type, except constants<span style="font-family: 宋体">Q?/span><br />           5<span style="font-family: 宋体">Q、一个指向类加蝲器的引用Q?/span>A reference to class ClassLoader<span style="font-family: 宋体">Q?/span><br />           6<span style="font-family: 宋体">Q、一个指?/span>Class<span style="font-family: 宋体">cȝ引用Q?/span>A reference to class Class<span style="font-family: 宋体">Q?/span></p> <p><br />           1<span style="font-family: 宋体">Q、类型的帔R池(</span>The constant pool for the type<span style="font-family: 宋体">Q?/span><br />           <span style="font-family: 宋体">帔R池中保存中所有类型是用的有序的常量集合,包含直接帔RQ?/span>literals<span style="font-family: 宋体">Q如字符丌Ӏ整数、QҎ(gu)的常量,和对cd、字Dc(din)方法的W号引用。常量池</span> <span style="font-family: 宋体">中每一个保存的帔R都有一个烦引,像数组中的字段一栗因为常量池中保存中所有类型用到的类型、字Dc(din)方法的字符引用Q所以它也是动态连接的主要?/span> <span style="font-family: 宋体">象。详l信息参见第六章</span>“The Java Class File”<span style="font-family: 宋体">?/span><br />           2<span style="font-family: 宋体">Q、类型字D늚信息Q?/span>Field information<span style="font-family: 宋体">Q?/span><br />           <span style="font-family: 宋体">字段名、字D늱型、字D늚修饰W(</span>public<span style="font-family: 宋体">Q?/span>private<span style="font-family: 宋体">Q?/span>protected<span style="font-family: 宋体">Q?/span>static<span style="font-family: 宋体">Q?/span>final<span style="font-family: 宋体">Q?/span>volatile<span style="font-family: 宋体">Q?/span>transient<span style="font-family: 宋体">{)、字D在cM定义的顺序?/span><br />           3<span style="font-family: 宋体">Q、类型方法的信息Q?/span>Method information<span style="font-family: 宋体">Q?/span><br />           <span style="font-family: 宋体">Ҏ(gu)名、方法的q回值类型(或者是</span>void<span style="font-family: 宋体">Q、方法参数的个数、类型和他们的顺序、字D늚修饰W(</span>public<span style="font-family: 宋体">Q?/span>private<span style="font-family: 宋体">Q?/span>protected<span style="font-family: 宋体">Q?/span>static<span style="font-family: 宋体">Q?/span>final<span style="font-family: 宋体">Q?/span>volatile<span style="font-family: 宋体">Q?/span>transient<span style="font-family: 宋体">{)、方法在cM定义的顺?/span><br />           <span style="font-family: 宋体">如果不是抽象和本地本法还需要保?/span><br />           <span style="font-family: 宋体">Ҏ(gu)的字节码、方法的操作数堆栈的大小和本地变量区的大(E候有详细信息Q、异常列表(详细信息参见W十七章</span>“Exceptions”<span style="font-family: 宋体">。)</span><br />           4<span style="font-family: 宋体">Q、类Q静态)变量Q?/span>Class Variables<span style="font-family: 宋体">Q?/span><br />           <span style="font-family: 宋体">cd量被所有类的实例共享,即不通过cȝ实例也可以访问。这些变量绑定在cMQ而不是类的实例上Q,所以他们是cȝ逻辑数据的一部分。在</span>Java<span style="font-family: 宋体">虚拟Z用这个类之前需要ؓ(f)cd量(</span>non-final<span style="font-family: 宋体">Q分配内?/span><br />           <span style="font-family: 宋体">帔RQ?/span>final<span style="font-family: 宋体">Q的处理方式于这U类变量Q?/span>non-final<span style="font-family: 宋体">Q不一栗每一个类型在用到一个常量的时候,都会(x)复制一份到自己的常量池中。常量也像类?/span> <span style="font-family: 宋体">量一样保存在Ҏ(gu)ZQ只不过他保存在帔R池中。(可能是,cd量被所有实例共享,而常量池是每个实例独有的Q?/span>Non-final<span style="font-family: 宋体">cd量保存ؓ(f)定义他的</span> <span style="font-family: 宋体">cd数据Q?/span>data for the type that declares them<span style="font-family: 宋体">Q的一部分Q?/span>final<span style="font-family: 宋体">帔R保存Z用他的类型数据(</span>data for any type that uses them<span style="font-family: 宋体">Q的一部分。详情参见第六章</span>“The Java Class FileThe Java Class File”<br />           5<span style="font-family: 宋体">Q、指向类加蝲器的引用Q?/span>A reference to class ClassLoader<span style="font-family: 宋体">Q?/span><br />           <span style="font-family: 宋体">每一个被</span>Java<span style="font-family: 宋体">虚拟机加载的cdQ虚拟机必须保存q个cd是否由原始类加蝲器或者类加蝲器加载。那些被cd载器加蝲的类型必M存一个指向类加蝲器的?/span> <span style="font-family: 宋体">用。当cd载器动态连接时Q会(x)使用q条信息。当一个类引用另一个类Ӟ虚拟机必M存那个被引用的类型是被同一个类加蝲器加载的Q这也是虚拟机维护不同命</span> <span style="font-family: 宋体">名空间的q程。详情参见第八章</span>“The Linking Model”<br />           6<span style="font-family: 宋体">Q、指?/span>Class<span style="font-family: 宋体">cȝ引用Q?/span>A reference to class Class<span style="font-family: 宋体">Q?/span><br />           Java<span style="font-family: 宋体">虚拟Zؓ(f)每一个加载的cd创徏一?/span>java.lang.Class<span style="font-family: 宋体">cȝ实例。你也可以通过</span>Class<span style="font-family: 宋体">cȝҎ(gu)Q?/span><br /> public static Class forName(String className)<span style="font-family: 宋体">来查找或者加载一个类Qƈ取得相应?/span>Class<span style="font-family: 宋体">cȝ实例。通过q个</span>Class<span style="font-family: 宋体">cȝ实例Q我们可以访?/span>Java<span style="font-family: 宋体">虚拟机方法区中的信息。具体参?/span>Class<span style="font-family: 宋体">cȝ</span>JavaDoc<span style="font-family: 宋体">?/span><br />      2<span style="font-family: 宋体">、方法列表(</span>Method Tables<span style="font-family: 宋体">Q?/span><br />      <span style="font-family: 宋体">Z更有效的讉K所有保存在Ҏ(gu)Z的数据,q些数据的存储结构必ȝq仔l的设计。所有方法区中,除了保存了上边的那些原始信息外,q有一个ؓ(f)了加快存</span> <span style="font-family: 宋体">取速度而设计的数据l构Q比如方法列表。每一个被加蝲的非抽象c,</span>Java<span style="font-family: 宋体">虚拟机都?x)?f)他们产生一个方法列表,q个列表中保存了q个cd能调用的所有实?/span> <span style="font-family: 宋体">Ҏ(gu)的引用,报错那些父类中调用的Ҏ(gu)。详情参见第八章</span>“The Linking Model”</p> <p>         <strong><span style="font-family: 宋体">八、堆</span></strong><br />      <span style="font-family: 宋体">?/span>Java<span style="font-family: 宋体">E序创徏一个类的实例或者数l时Q都在堆中ؓ(f)新的对象分配内存。虚拟机中只有一个堆Q所有的U程都共享他?/span><br />      1<span style="font-family: 宋体">、垃圾收集(</span>Garbage Collection<span style="font-family: 宋体">Q?/span><br />      <span style="font-family: 宋体">垃圾攉是释放没有被引用的对象的主要Ҏ(gu)。它也可能会(x)Z减少堆的片Q而移动对象。在</span>Java<span style="font-family: 宋体">虚拟机的规范中没有严格定义垃圾收集,只是定义一?/span>Java<span style="font-family: 宋体">虚拟机的实现必须通过某种方式理自己的堆。详情参见第?ji)?/span>“Garbage Collection”<span style="font-family: 宋体">?/span><br />      2<span style="font-family: 宋体">、对象存储结构(</span>Object Representation<span style="font-family: 宋体">Q?/span><br />      Java<span style="font-family: 宋体">虚拟机的规范中没有定义对象怎样在堆中存储。每一个对象主要存储的是他的类和父cM定义的对象变量。对于给定的对象的引用,虚拟机必d耨很快的</span> <span style="font-family: 宋体">定位到这个对象的数据。另为,必须提供一U通过对象的引用方法对象数据的Ҏ(gu)Q比如方法区中的对象的引用,所以一个对象保存的数据中往往含有一个某UŞ?/span> <span style="font-family: 宋体">指向Ҏ(gu)区的指针?/span><br />      <span style="font-family: 宋体">一个可能的堆的设计是将堆分Z个部分:(x)引用池和对象池。一个对象的引用是指向引用池的本地指针。每一个引用池中的条目都包含两个部分:(x)指向对象池中?/span> <span style="font-family: 宋体">象数据的指针和方法区中对象类数据的指针。这U设计能够方?/span>Java<span style="font-family: 宋体">虚拟机堆片的整理。当虚拟机在对象池中Ud一个对象的时候,只需要修改对应引用池?/span> <span style="font-family: 宋体">的指针地址。但是每ơ访问对象的数据都需要处理两ơ指针。下图演CZq种堆的设计。在W九(ji)章的</span>“<span style="font-family: 宋体">垃圾攉</span>”<span style="font-family: 宋体">中的</span>HeapOfFish Applet<span style="font-family: 宋体">演示了这U设计?/span> <br />      <span style="font-family: 宋体">另一U堆的设计是Q一个对象的引用是一个指向一堆数据和指向相应对象的偏UL针。这U设计方便了对象的访问,可是对象的移动要变的异常复杂。下图演CZq种设计</span> <br />      <span style="font-family: 宋体">当程序试囑ְ一个对象{换ؓ(f)另一U类型时Q虚拟机需要判断这U{换是否是q个对象的类型,或者是他的父类型。当E序适用</span>instanceof<span style="font-family: 宋体">语句的时候也</span> <span style="font-family: 宋体">?x)做cM的事情。当E序调用一个对象的Ҏ(gu)Ӟ虚拟机需要进行动态绑定,他必d断调用哪一个类型的Ҏ(gu)。这也需要做上面的判断?/span><br />      <span style="font-family: 宋体">无论虚拟机实现者用哪一U设计,他都可能为每一个对象保存一个类似方法列表的信息。因Z可以提升对象Ҏ(gu)调用的速度Q对提升虚拟机的性能非常重要Q但</span> <span style="font-family: 宋体">是虚拟机的规范中比没有要求必d现类似的数据l构。下图描qCq种l构。图中显CZ一个对象引用相兌的所有的数据l构Q包括:(x)</span><br />           1<span style="font-family: 宋体">Q、一个指向类型数据的指针</span><br />           2<span style="font-family: 宋体">Q、一个对象的Ҏ(gu)列表。方法列表是一个指向所有可能被调用对象Ҏ(gu)的指针数l。方法数据包括三个部分:(x)操作码堆栈的大小和方法堆栈的本地变量区;Ҏ(gu)的字节码Q异常列表?/span><br />           <span style="font-family: 宋体">每一?/span>Java<span style="font-family: 宋体">虚拟Z的对象必d联一个用于同步多U程?/span>lock(mutex)<span style="font-family: 宋体">。同一时刻Q只能有一个对象拥有这个对象的锁。当一个拥有这个这个对?/span> <span style="font-family: 宋体">的锁Q他可以多ơ申误个锁Q但是也必须释放相应ơ数的锁才能真正释放q个对象锁。很多对象在整个生命周期中都不会(x)被锁Q所以这个信息只有在需要时才需</span> <span style="font-family: 宋体">要添加。很?/span>Java<span style="font-family: 宋体">虚拟机的实现都没有在对象的数据中包含</span>“<span style="font-family: 宋体">锁定数据</span>”<span style="font-family: 宋体">Q只是在需要时才生成相应的数据。除了实现对象的锁定Q每一个对象还逻辑兌C</span> <span style="font-family: 宋体">?/span>“wait set”<span style="font-family: 宋体">的实现。锁定帮l线E独立处理共享的数据Q不需要妨其他的U程?/span>“wait set”<span style="font-family: 宋体">帮组U程协作完成同一个目标?/span>“wait set”<span style="font-family: 宋体">往往通过</span>Object<span style="font-family: 宋体">cȝ</span>wait()<span style="font-family: 宋体">?/span>notify()<span style="font-family: 宋体">Ҏ(gu)来实现?/span> <br />      <span style="font-family: 宋体">垃圾攉也需要堆中的对象是否被关联的信息?/span>Java<span style="font-family: 宋体">虚拟范中指出垃圾攉一个运行一个对象的</span>finalizer<span style="font-family: 宋体">Ҏ(gu)一ơ,但是容许</span> finalizer<span style="font-family: 宋体">Ҏ(gu)重新引用q个对象Q当q个对象再次不被引用Ӟ׃需要再ơ调?/span>finalize<span style="font-family: 宋体">Ҏ(gu)。所以虚拟机也需要保?/span>finalize<span style="font-family: 宋体">Ҏ(gu)</span> <span style="font-family: 宋体">是否q行q的信息。更多信息参见第?ji)章?/span>“<span style="font-family: 宋体">垃圾攉</span>”<br />      3<span style="font-family: 宋体">、数l的保存Q?/span>Array Representation<span style="font-family: 宋体">Q?/span><br /> <span style="font-family: 宋体">?/span>Java <span style="font-family: 宋体">中,数组是一U完全意义上的对象,他和对象一样保存在堆中、有一个指?/span>Class<span style="font-family: 宋体">cd例的引用。所有同一l度和类型的数组拥有同样?/span>Class<span style="font-family: 宋体">Q数l的?/span> <span style="font-family: 宋体">度不做考虑。对?/span>Class<span style="font-family: 宋体">的名字表CZؓ(f)l度和类型。比如一个整型数据的</span>Class<span style="font-family: 宋体">?/span>“[I”<span style="font-family: 宋体">Q字节型三维数组</span>Class<span style="font-family: 宋体">名ؓ(f)</span>“[[[B”<span style="font-family: 宋体">Q两l对象数?/span> Class<span style="font-family: 宋体">名ؓ(f)</span>“[[Ljava.lang.Object”<span style="font-family: 宋体">?/span><br /> <span style="font-family: 宋体">多维数组被表CZؓ(f)数组的数l,如下图:(x)</span> <br />      <span style="font-family: 宋体">数组必须在堆中保存数l的长度Q数l的数据和一些对象数l类型数据的引用。通过一个数l引用的Q虚拟机应该能够取得一个数l的长度Q通过索引能够讉K特定</span> <span style="font-family: 宋体">的数据,能够调用</span>Object<span style="font-family: 宋体">定义的方法?/span>Object<span style="font-family: 宋体">是所有数据类的直接父cR更多信息参见第六章</span>“<span style="font-family: 宋体">cL?/span>”<span style="font-family: 宋体">?/span><br /> <strong><span style="font-family: 宋体">?ji)?/span></strong><strong><span style="font-family: 'Calibri','sans-serif'">PC</span></strong><strong><span style="font-family: 宋体">寄存器(E序计数器)Q?/span></strong><strong><span style="font-family: 'Calibri','sans-serif'">The Program Counter</span></strong><strong><span style="font-family: 宋体">Q?/span></strong><br />      <span style="font-family: 宋体">每一个线E开始执行时都会(x)被创Z个程序计数器。程序计数器只有一个字长(</span>word<span style="font-family: 宋体">Q,所以它能够保存一个本地指针和</span>returnValue<span style="font-family: 宋体">。当U程执行</span> <span style="font-family: 宋体">ӞE序计数器中存放了正在执行指令的地址Q这个地址可以使一个本地指针,也可以一个从Ҏ(gu)字节码开始的偏移指针。如果执行本地方法,E序计数器的值没</span> <span style="font-family: 宋体">有被定义?/span><br /> <strong><span style="font-family: 宋体">十?/span></strong><strong><span style="font-family: 'Calibri','sans-serif'">Java</span></strong><strong><span style="font-family: 宋体">堆栈Q?/span></strong><strong><span style="font-family: 'Calibri','sans-serif'">The Java Stack</span></strong><strong><span style="font-family: 宋体">Q?/span></strong><br />      <span style="font-family: 宋体">当一个线E启动时Q?/span>Java<span style="font-family: 宋体">虚拟Z(x)Z创徏一?/span>Java<span style="font-family: 宋体">堆栈?/span>Java<span style="font-family: 宋体">堆栈用一些离散的</span>frame<span style="font-family: 宋体">cȝ录线E的状态?/span>Java<span style="font-family: 宋体">虚拟机堆</span>Java<span style="font-family: 宋体">堆栈的操作只有两U:(x)压入和弹?/span>frames<span style="font-family: 宋体">?/span><br />      <span style="font-family: 宋体">U程中正在执行的Ҏ(gu)被称为当前方法(</span>current method<span style="font-family: 宋体">Q,当前Ҏ(gu)所对应?/span>frame<span style="font-family: 宋体">被称为当前Q?/span>current frame<span style="font-family: 宋体">Q。定义当前方法的c被UCؓ(f)当前c(</span>current class<span style="font-family: 宋体">Q,当前cȝ帔R池被UCؓ(f)当前帔R池(</span>current constant pool.<span style="font-family: 宋体">Q。当U程执行Ӟ</span>Java<span style="font-family: 宋体">虚拟Z(x)跟踪当前cd当前帔R池。但U程操作保存在中的数据Ӟ他只操作当前帧的数据?/span><br />      <span style="font-family: 宋体">当线E调用一个方法时Q虚拟机?x)生成一个新的Qƈ压入U程?/span>Java<span style="font-family: 宋体">堆栈。这个新的变成当前帧。当Ҏ(gu)执行Ӟ他用当前保存Ҏ(gu)的参数、本地变</span> <span style="font-family: 宋体">量、中间结构和其他数据。方法有两种退出方式:(x)正常退出和异常推出。无论方法以哪一U方式推出,</span>Java<span style="font-family: 宋体">虚拟机都?x)弹出ƈ丢弃?gu)的Q上一个方法的帧变</span> <span style="font-family: 宋体">为当前?/span><br />      <span style="font-family: 宋体">所有保存在帧中的数据都只能被拥有它的线E访问,U程不能讉K其他U程的堆栈中的数据。所以,讉KҎ(gu)的本地变量时Q不需要考虑多线E同步?/span><br />      <span style="font-family: 宋体">和方法区、堆一P</span>Java<span style="font-family: 宋体">堆栈不需要连l的内存I间Q它可以被保存在一个分散的内存I间或者堆上。堆栈具体的数据和长度都?/span>Java<span style="font-family: 宋体">虚拟机的实现者自己定义。一些实现可能提供了执行堆栈最大值和最值的Ҏ(gu)?/span><br /> <strong><span style="font-family: 宋体">十一、堆栈Q?/span></strong><strong><span style="font-family: 'Calibri','sans-serif'">The Stack Frame</span></strong><strong><span style="font-family: 宋体">Q?/span></strong><br />      <span style="font-family: 宋体">堆栈帧包含三部分Q本地变量、操作数堆栈和数据。本地变量和操作数堆栈的大小都是一字(</span>word<span style="font-family: 宋体">Qؓ(f)单位的,他们在编译就已经定。数据的大取决于</span> <span style="font-family: 宋体">不同的实现。当E序调用一个方法时Q虚拟机从类数据中取得本地变量和操作数堆栈的大小Q创Z个合适大和帧,然后压入</span>Java<span style="font-family: 宋体">堆栈中?/span><br />      1<span style="font-family: 宋体">、本地变量(</span>Local Variables<span style="font-family: 宋体">Q?/span><br />      <span style="font-family: 宋体">本地变量?/span>Java<span style="font-family: 宋体">堆栈帧中被组lؓ(f)一个从</span>0<span style="font-family: 宋体">计数的数l,指o(h)通过提供他们的烦引从本地变量Z取得相应的倹{?/span>Int,float,reference, returnValue<span style="font-family: 宋体">占一个字Q?/span>byte,short,char<span style="font-family: 宋体">被{换成</span>int<span style="font-family: 宋体">然后存储Q?/span>long<span style="font-family: 宋体">?/span>doubel<span style="font-family: 宋体">占两个字?/span><br />      <span style="font-family: 宋体">指o(h)通过提供两个字烦引中的前一个来取得</span>long,doubel<span style="font-family: 宋体">的倹{比如一?/span>long<span style="font-family: 宋体">的值存储在索引</span>3<span style="font-family: 宋体">Q?/span>4<span style="font-family: 宋体">上,指o(h)可以通过</span>3<span style="font-family: 宋体">来取得这?/span>long<span style="font-family: 宋体">cd的倹{?/span><br />      <span style="font-family: 宋体">本地变量Z包含了方法的参数和本地变量。编译器方法的参数以他们申明的序攑֜数组的前面。但是编译器却可以将本地变量L排列在本地变量数l中Q甚至两个本地变量可以公用一个地址Q比如,当两个本地变量在两个不交叠的区域内,像循环变量</span>i,j<span style="font-family: 宋体">?/span><br />      <span style="font-family: 宋体">虚拟机的实现者可以用Q何结构来描述本地变量Z的数据,虚拟范中没有定义如何存储</span>long<span style="font-family: 宋体">?/span>doubel<span style="font-family: 宋体">?/span><br />      2<span style="font-family: 宋体">、操作数堆栈Q?/span>Operand Stack<span style="font-family: 宋体">Q?/span><br />      <span style="font-family: 宋体">向本地变量一P操作数堆栈也被组lؓ(f)一个以字ؓ(f)单位的数l。但是不像本地变量那样通过索引讉KQ而是通过</span>push<span style="font-family: 宋体">?/span>pop<span style="font-family: 宋体">值来实现讉K的。如果一个指?/span>push<span style="font-family: 宋体">一个值到堆栈中,那么下一个指令就可以</span>pop<span style="font-family: 宋体">q且使用q个倹{?/span><br />      <span style="font-family: 宋体">操作数堆栈不像程序计数器那样不可以被指o(h)直接讉KQ指令可以直接访问操作数堆栈?/span>Java<span style="font-family: 宋体">虚拟机是一个以堆栈为基Q而不是以寄存器ؓ(f)基础的,因ؓ(f)它的</span> <span style="font-family: 宋体">指o(h)从堆栈中取得操作敎ͼ而不是同寄存器中。当Ӟ指o(h)也可以从其他地方ȝ操作敎ͼ比如指o(h)后面的操作码Q或者常量池。但?/span>Java<span style="font-family: 宋体">虚拟机指令主要是?/span> <span style="font-family: 宋体">操作数堆栈中取得他们需要的操作数?/span><br />      Java<span style="font-family: 宋体">虚拟机将操作数堆栈视为工作区Q很多指令通过先从操作数堆栈中</span>pop<span style="font-family: 宋体">|在处理完以后再将l果</span>push<span style="font-family: 宋体">回操作数堆栈。一?/span>add<span style="font-family: 宋体">的指令执行过E如</span> <span style="font-family: 宋体">下图所C:(x)先执?/span>iload_0<span style="font-family: 宋体">?/span>iload_1<span style="font-family: 宋体">两条指o(h)需要相加的两个敎ͼ从本地方法区中取出,q?/span>push<span style="font-family: 宋体">到操作数堆栈中;然后执行</span>iadd<span style="font-family: 宋体">指o(h)Q现</span> pop<span style="font-family: 宋体">Z个|相加Qƈ结?/span>pusp<span style="font-family: 宋体">q操作数堆栈中;最后执?/span>istore_2<span style="font-family: 宋体">指o(h)Q?/span>pop<span style="font-family: 宋体">出结果,赋值到本地Ҏ(gu)Z?/span> <br />      3<span style="font-family: 宋体">、数据Q?/span>Frame Data<span style="font-family: 宋体">Q?/span><br />      <span style="font-family: 宋体">处理本地变量和操作数堆栈以外Q?/span>java<span style="font-family: 宋体">堆栈帧还包括了ؓ(f)了支持常量池Q方法返回值和异常分发需要的数据Q他们被保存在数据中?/span><br />      <span style="font-family: 宋体">当虚拟机遇到使用指向帔R池引用的指o(h)Ӟ׃(x)通过帧数据中指向帔R区的指针来访问所需要的信息。前面提到过Q常量区中的引用在最开始时都是W号引用。即使当虚拟机检查这些引用时Q他们也是字W引用。所以虚拟机需要在q时转换q个引用?/span><br />      <span style="font-family: 宋体">当一个方法正常返回时Q虚拟机需要重建那个调用这个方法的Ҏ(gu)的堆栈。如果执行完的方法有q回|虚拟机就需要将q个?/span>push<span style="font-family: 宋体">q调用方法的哪个操作数堆栈中?/span><br />      <span style="font-family: 宋体">帧数据中也包含虚拟机用来处理异常的异常表的引用。异常表定义了一个被</span>catch<span style="font-family: 宋体">语句保护的一D字节码。每一个异常表中的个体又包含了需要保护的字节玛的</span> <span style="font-family: 宋体">范围Q和异常被捕捉到旉要执行的字节码的位置。当一个方法抛Z个异常时Q?/span>Java<span style="font-family: 宋体">虚拟机就是用异常表去判断如何处理q个异常。如果虚拟机扑ֈ了一个匹</span> <span style="font-family: 宋体">配的</span>catch<span style="font-family: 宋体">Q他׃(x)控制权交给</span>catch<span style="font-family: 宋体">语句。如果没有找到匹配的</span>catch<span style="font-family: 宋体">Q方法就?x)异常返回,然后再调用的?gu)中l这个过E?/span><br />      <span style="font-family: 宋体">除了以上的三个用途外Q数据q可能包含一些依赖于实现的数据,比如调试的信息?/span><br /> <strong><span style="font-family: 宋体">十二、本地方法堆?/span></strong><br />      <span style="font-family: 宋体">本地Ҏ(gu)Z赖于虚拟机的不同实现。虚拟机的实现者可以自己决定用哪一U机制去执行本地Ҏ(gu)?/span><br />      <span style="font-family: 宋体">M本地Ҏ(gu)接口Q?/span>Native Method Interface<span style="font-family: 宋体">Q都使用某种形式的本地方法堆栈?/span> <br /> <strong><span style="font-family: 宋体">十三、执行引?/span></strong><br />      <span style="font-family: 宋体">一?/span>java<span style="font-family: 宋体">虚拟机实现的核心?yu)是执行引擎。在</span>Java<span style="font-family: 宋体">虚拟范,执行引擎被描qCؓ(f)一pd的指令。对于每一个指令,规范都描qC他们应该做什么,但是没有说要如何d?/span><br />      1<span style="font-family: 宋体">、指令集</span><br />      <span style="font-family: 宋体">?/span>Java<span style="font-family: 宋体">虚拟Z一个方法的字节码流是一个指令的序列。每一个指令由一个字节的操作码(</span>Opcode<span style="font-family: 宋体">Q和可能存在的操作数Q?/span>Operands<span style="font-family: 宋体">Q。操?/span> <span style="font-family: 宋体">码指C去做什么,操作数提供一些执行这个操作码可能需要的额外的信息。一个抽象的执行引擎每次执行一个指令。这个过E发生在每一个执行的U程中?/span><br /> <span style="font-family: 宋体">有时Q执行引擎可能会(x)遇到一个需要调用本地方法的指o(h)Q在q种情况下,执行引擎?x)去试图调用本地?gu)Q但本地Ҏ(gu)q回Ӟ执行引擎?x)l执行字节码中的下一个指令。本地方法也可以看成?/span>Java<span style="font-family: 宋体">虚拟Z的指令集的一U扩充?/span><br />      <span style="font-family: 宋体">军_下一步执行那一条指令也是执行引擎工作的一部分。执行引擎有三种Ҏ(gu)d得下一条指令。多数指令会(x)执行跟在他会(x)面的指o(h)Q一些像</span>goto<span style="font-family: 宋体">Q?/span> return<span style="font-family: 宋体">的指令,?x)在他们执行的时候决定他们的下一条指令;当一个指令抛出异常时Q执行引擎通过匚w</span>catch<span style="font-family: 宋体">语句来决定下一条应该执行的指o(h)?/span><br />      <span style="font-family: 宋体">q_独立性、网l移动性?/span><a target="_blank"><span style="color: windowtext; font-family: 宋体; text-decoration: none; text-underline: none">安全</a></span><span style="font-family: 宋体">性左右了</span>Java<span style="font-family: 宋体">虚拟机指令集的设计。^台独立性是指o(h)集设计的主要影响因素之一。基于堆栈的l构使得</span>Java<span style="font-family: 宋体">虚拟机可以在</span> <span style="font-family: 宋体">更多的^C实现。更的操作码,紧凑的结构得字节码可以更有效的利用|络带宽。一ơ性的字节码验证,使得字节码更安全Q而不影响太多的性能?/span><br />      2<span style="font-family: 宋体">、执行技?/span><br />      <span style="font-family: 宋体">许多U执行技术可以用?/span>Java<span style="font-family: 宋体">虚拟机的实现中:(x)解释执行Q及(qing)时编译(</span>just-in-time compiling<span style="font-family: 宋体">Q,</span>hot-spot compiling,native execution in silicon<span style="font-family: 宋体">?/span><br />      3<span style="font-family: 宋体">、线E?/span><br />      Java<span style="font-family: 宋体">虚拟范定义了一Uؓ(f)了在更多q_上实现的U程模型?/span>Java<span style="font-family: 宋体">U程模型的一个目标时可以利用本地U程。利用本地线E可以让</span>Java<span style="font-family: 宋体">E序中的U程能过在多处理器机器上真正的同时执行?/span><br />      Java<span style="font-family: 宋体">U程模型的一个代价就是线E优先Q一?/span>Java<span style="font-family: 宋体">U程可以?/span>1-10<span style="font-family: 宋体">的优先上运行?/span>1<span style="font-family: 宋体">最低,</span>10<span style="font-family: 宋体">最高。如果设计者用了本地U程Q他们可能将q?/span> 10<span style="font-family: 宋体">个优先映射到本C先上?/span>Java<span style="font-family: 宋体">虚拟范只定义了,高一点优先的线E可以却一?/span>cpu<span style="font-family: 宋体">旉Q低优先U的U程在所有高优先U线E都堵塞Ӟ?/span> <span style="font-family: 宋体">可以获取一?/span>cpu<span style="font-family: 宋体">旉Q但是这没有保证Q低优先U的U程在高优先U线E没有堵塞时不可以获得一定的</span>cpu<span style="font-family: 宋体">旉。因此,如果需要在不同的线E间协作Q你?/span> <span style="font-family: 宋体">M用的</span>“<span style="font-family: 宋体">同步Q?/span>synchronizatoin<span style="font-family: 宋体">Q?/span>”<span style="font-family: 宋体">?/span><br />      <span style="font-family: 宋体">同步意味着两个部分Q对象锁Q?/span>object locking<span style="font-family: 宋体">Q和U程{待、激z?/span>(thread wait and notify)<span style="font-family: 宋体">。对象锁帮助U程可以不受其他U程的干扰。线E等待、激zd以让不同的线E进行协作?/span><br />      <span style="font-family: 宋体">?/span>Java<span style="font-family: 宋体">虚拟机的规范中,</span>Java<span style="font-family: 宋体">U程被描qCؓ(f)变量、主内存、工作内存。每一?/span>Java<span style="font-family: 宋体">虚拟机的实例都有一个主内存Q他包含了所有程序的变量Q对象、数l合cd量。每一个线E都有自q工作内存Q他保存了哪些他可能用到的变量的拯。规则:(x)</span><br />           1<span style="font-family: 宋体">Q、从d存拷贝变量的值到工作内存?/span><br />           2<span style="font-family: 宋体">Q、将工作内存中的值写?x)主内存?/span><br />      <span style="font-family: 宋体">如果一个变量没有被同步化,U程可能以Q何顺序更C内存中的变量。ؓ(f)了保证多U程E序的正的执行Q必M用同步机制?/span><br /> <strong><span style="font-family: 宋体">十四、本地方法接口(</span></strong><strong><span style="font-family: 'Calibri','sans-serif'">Native Method Interface</span></strong><strong><span style="font-family: 宋体">Q?/span></strong><br />      Java<span style="font-family: 宋体">虚拟机的实现q不是必d现本地方法接口。一些实现可能根本不支持本地Ҏ(gu)接口?/span>Sun<span style="font-family: 宋体">的本地方法接口是</span>JNI(Java Native Interface)<span style="font-family: 宋体">?/span><br /> <strong><span style="font-family: 宋体">十五、现实中的机器(</span></strong><strong><span style="font-family: 'Calibri','sans-serif'">The Real Machine</span></strong><strong><span style="font-family: 宋体">Q?/span></strong><br /> <strong><span style="font-family: 宋体">十六、数学方法:(x)仿真</span></strong><strong><span style="font-family: 'Calibri','sans-serif'">(Eternal Math : A Simulation)</span></strong></p><img src ="http://www.tkk7.com/anwenhao/aggbug/174972.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/anwenhao/" target="_blank">安文?/a> 2008-01-13 13:37 <a href="http://www.tkk7.com/anwenhao/archive/2008/01/13/174972.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DB2 LOAD 命o(h)(转蝲)http://www.tkk7.com/anwenhao/archive/2007/09/05/142912.html安文?/dc:creator>安文?/author>Wed, 05 Sep 2007 07:19:00 GMThttp://www.tkk7.com/anwenhao/archive/2007/09/05/142912.htmlhttp://www.tkk7.com/anwenhao/comments/142912.htmlhttp://www.tkk7.com/anwenhao/archive/2007/09/05/142912.html#Feedback0http://www.tkk7.com/anwenhao/comments/commentRss/142912.htmlhttp://www.tkk7.com/anwenhao/services/trackbacks/142912.html
?DB2 ?LOAD 实用E序为实现快速导入数据的功能Q除采用了通过直接向数据库中写入格式化的数据页装蝲数据Q导入过E中不激z触发器Q不?x)检查参考完整性和表检查约束当{方式外Q还最化了记录事务日志的操作。在 LOAD ?LOAD、BUILD、DELETE ?INDEX COPY 四个处理阶段中,仅在 DELETE 阶段记录Ҏ(gu)个删除事件记日志Q即只对每个q反唯一U束的行的删除操作记日志Q因此整?LOAD 操作仅记录了极少的日志?br />
׃ LOAD 最化了日志的记录Q有因启用了前滚恢复的数据库在恢复在U备份时需要归档日志的Ҏ(gu),对于q种数据库的 LOAD 操作Qؓ(f)避免执行 LOAD 操作后,表在使用 ROLLFORWARD 命o(h)前滚归档日志的过E中因缺日志而被|ؓ(f)非正常状态,DB2 ?LOAD 命o(h)提供了如下选项Q?br />
·COPY NOQ缺省)
·COPY YES
·NONREVERABLE

为更清楚地说明这些选项的作用,q里以举例的方式进行说明。而在开始操作之前,首先了解一?DB2 备䆾操作所产生的映象文件的形式和命名特点:(x)

?UNIX 环境下是文g的Ş式:(x)
Databasealias.Type.Instancename.Nodename.Catnodename.Timestamp.number

?Windows 环境下是子目录及(qing)文g的Ş式:(x)
Databasealias.Type\Instancename\Node0000\Catn0000\yyyymmdd\hhmmss.number

而其中的 Type 则因备䆾cd的不同而不同:(x)

0 -- 数据库全备䆾
3 -- 表空间备?br /> 4 -- ?LOAD 操作产生的备?br />

1. q行一ơ数据库的全备䆾Q?br />
首先对已启用前滚恢复模式?SAMPLE 数据库进行一ơ全备䆾Q?br />
E:\TEST>db2 backup db sample
备䆾成功。此备䆾映像的时间戳记是Q?0051230174105

q时看到在当前目录下产生了一?SAMPLE.0 的子目录Q表明生的是一个数据库全备份。下面将对这些现象逐个予以举例说明Q?br />

2. 关于 COPY NOQ?br />
?LOAD 操作l束Ӟ表所在的表空间置?#8220;备䆾暂挂”状态,此时虽然其中的表可以q行 SELECT 操作Q但不能q行 UPDATE ?DELETE 操作。ؓ(f)使该表状态恢复正常,除去备䆾暂挂状态,必须手动对其表空间执行一?BACKUP 命o(h)。由于该选项为缺省选项Q如?LOAD 命o(h)中未指明Q则默认Z用该选项Q如Q?br />
E:\TEST>db2 connect to sample

E:\TEST>db2 load from staff.del of del insert into staff

E:\TEST>db2 list tablespaces

Q?br /> 表空间标?= 2
名称 = USERSPACE1
cd = pȝ理I间
内容 = M数据
状?= 0x0020
详细解释Q?br /> 备䆾暂挂
Q?br />
E:\TEST>db2 select count(*) from staff
1
-----------
70
1 条记录已选择?br />
E:\TEST>db2 update staff set id=335 where id=340
DB21034E 该命令被当作 SQL 语句来处理,因ؓ(f)它不是有效的“命o(h)行处理器”命o(h)。在 SQL 处理期间Q它q回Q?br /> SQL0290N 不允许存取表I间?SQLSTATE=55039

在手动对 USERSPACE1 表空间进行一ơ备份操作后Q表I间状态将正常Q再ơ尝试更新操作就?x)成功?x)

E:\TEST>db2 backup db sample tablespace (userspace1)
备䆾成功。此备䆾映像的时间戳记是Q?0051230184841

命o(h)完成后可以在当前目录下看C生了一?SAMPLE.3 的子目录Q表明生的是一个表I间U的备䆾?br />
E:\TEST>db2 connect to sample

E:\TEST>db2 list tablespaces

表空间标?= 2
名称 = USERSPACE1
cd = pȝ理I间
内容 = M数据
状?= 0x0000
详细解释Q?br /> 正常

而所产生q䆾关于表空间的备䆾可在数据库因前滚操作表I间|ؓ(f)“复原暂挂”状态时用于表I间状态恢复ؓ(f)正常Qƈ恢复 LOAD 操作对该表的修改。如当前滚数据库过 LOAD 旉点后Q表I间被|ؓ(f)复原暂挂状态:(x)

E:\TEST>db2 restore db sample taken at 20051230174105
DB20000I RESTORE DATABASE 命o(h)成功完成?br />
E:\TEST>db2 rollforward db sample to end of logs and stop
SQL1271W 已恢复数据库 "SAMPLE"Q但在节?"0"上有一个或多个表空间脱?br />
E:\TEST>db2 connect to sample

E:\TEST>db2 list tablespaces
表空间标?= 2
名称 = USERSPACE1
cd = pȝ理I间
内容 = M数据
状?= 0x0100
详细解释Q?br /> 复原暂挂

此时可利用这一表空间的备份进行恢复操作:(x)

E:\TEST>db2 restore db sample tablespace (userspace1) taken at 20051230184841
DB20000I RESTORE DATABASE 命o(h)成功完成?br />
E:\TEST>db2 connect to sample

E:\TEST>db2 list tablespaces
Q?br /> 表空间标?= 2
名称 = USERSPACE1
cd = pȝ理I间
内容 = M数据
状?= 0x0080
详细解释Q?br /> 前滚暂挂
Q?br />
E:\TEST>db2 rollforward db sample to end of logs and stop tablespace (userspace1)

前滚状?br />
输入数据库别?= sample
节点数已q回状?= 1

节点?= 0
前滚状?= 未暂?br /> 下一个要d的日志文?=
已处理的日志文g = -
上次落实的事?= 2005-12-30-10.47.10.000000

DB20000I ROLLFORWARD 命o(h)成功完成?br />
E:\TEST>db2 connect to sample

E:\TEST>db2 list tablespaces
:
表空间标?= 2
名称 = USERSPACE1
cd = pȝ理I间
内容 = M数据
状?= 0x0000
详细解释Q?br /> 正常
:

E:\TEST>db2 update staff set id=335 where id=340
DB20000I SQL 命o(h)成功完成?br />
可见表空间状态已正常Q表也可执行更新操作了?br />

3. 关于 COPY YESQ?br />
?LOAD 操作l束ӞDB2 自动对表所在的表空间进行一ơ备份操作,因?LOAD l束后,表所在的表空间不?x)再处?#8220;备䆾暂挂”状态,而ؓ(f)“正常”状态。但׃要进行备份操作,所以这U?LOAD 操作的时间会(x)较没有备份的ѝ如Q?br />
E:\TEST>db2 connect to sample

E:\TEST>db2 load from staff.del of del insert into staff copy yes to .

E:\TEST>db2 list tablespaces
:
表空间标?= 2
名称 = USERSPACE1
cd = pȝ理I间
内容 = M数据
状?= 0x0000
详细解释Q?br /> 正常
:

E:\TEST>db2 select count(*) from staff
1
-----------
105
1 条记录已选择?br />

此时可在当前目录下看C?SAMPLE.4 的子目录Q表明生的是一个由 LOAD 操作生成的备份,而这份备份将在数据库q行前滚恢复操作时用于重新创?LOAD 操作Ҏ(gu)据库的修攏V如Q?br />
E:\TEST>db2 restore db sample taken at 20051230174105
DB20000I RESTORE DATABASE 命o(h)成功完成?br />
E:\TEST>db2 rollforward db sample to end of logs and stop

前滚状?br />
输入数据库别?= sample
节点数已q回状?= 1

节点?= 0
前滚状?= 未暂?br /> 下一个要d的日志文?=
已处理的日志文g = S0000002.LOG - S0000003.LOG
上次落实的事?= 2005-12-30-11.48.26.000000

DB20000I ROLLFORWARD 命o(h)成功完成?br />
E:\TEST>db2 connect to sample

E:\TEST>db2 list tablespaces
:
表空间标?= 2
名称 = USERSPACE1
cd = pȝ理I间
内容 = M数据
状?= 0x0000
详细解释Q?br /> 正常
:

E:\TEST>db2 select count(*) from staff
1
-----------
105
1 条记录已选择?br />
q表明在 SAMPLE.4 下的备䆾被用于了前滚恢复操作Q而重新创Z LOAD 操作Ҏ(gu)据库插入的记录?br />

4. 关于 NONRECOVERABLEQ?br />
该选项?x)?LOAD 操作标志Z可恢复,x据库不能通过后箋的前滚操作而被恢复。LOAD 操作l束后,数据库既不会(x)处于“备䆾暂挂”状态,也不?x)生Q何的备䆾?br />
E:\TEST>db2 connect to sample

E:\TEST>db2 load from staff.del of del insert into staff nonrecoverable

E:\TEST>db2 list tablespaces
:
表空间标?= 2
名称 = USERSPACE1
cd = pȝ理I间
内容 = M数据
状?= 0x0000
详细解释Q?br /> 正常
:

虽然 LOAD 之后表空间和表的状态都正常Q但如果今后需要执行前滚命令恢复数据库Ӟ前滚操作蟩q?LOAD 事务的处理,而将 LOAD 的表标记为无效,是对表的M操作都不能进行。如Q?br />
E:\TEST>db2 restore db sample taken at 20051230174105
DB20000I RESTORE DATABASE 命o(h)成功完成?br />
E:\TEST>db2 rollforward db sample to end of logs and stop

前滚状?br />
输入数据库别?= sample
节点数已q回状?= 1

节点?= 0
前滚状?= 未暂?br /> 下一个要d的日志文?=
已处理的日志文g = S0000002.LOG - S0000003.LOG
上次落实的事?= 2005-12-30-12.19.55.000000

DB20000I ROLLFORWARD 命o(h)成功完成?br />
E:\>db2 connect to sample

E:\TEST>db2 list tablespaces
:
表空间标?= 2
名称 = USERSPACE1
cd = pȝ理I间
内容 = M数据
状?= 0x0000
详细解释Q?br /> 正常
:

E:\>db2 select * from staff

ID NAME DEPT JOB YEARS SALARY COMM
------ --------- ------ ----- ------ --------- ---------
SQL1477N 不能存取?"LIWENLI.STAFF"?SQLSTATE=55019

q表明该表已不可操作Q此时只有将表删除,重新构徏Q或使用 LOAD 操作旉点之后所做的数据库全备䆾或表I间备䆾来恢复该表?br />

5. 关于注册表变?DB2_LOAD_COPY_NO_OVERRIDE 的介l:(x)

另外 DB2 q提供了一个注册表变量QDB2_LOAD_COPY_NO_OVERRIDEQ可?LOAD 的缺省选项 COPY NO 讄?NONRECOVERABLE ?COPY YES。具体用方法D例ؓ(f)Q?br />
讄?COPY YES 的方?

E:\TEST>db2set DB2_LOAD_COPY_NO_OVERRIDE="COPY YES TO E:\TEST"
E:\TEST>db2 terminate
E:\TEST>db2set
DB2_LOAD_COPY_NO_OVERRIDE=COPY YES TO E:\TEST
:

E:\TEST>db2 load from staff.del of del insert into staff
SQL27966W DB2_LOAD_COPY_NO_OVERRIDE 注册表变量?"COPY YES TO E:\TEST" 覆盖在 Load 中指定的 COPY NO 参数?br /> :
:

讄?NONRECOVERABLE 的方?

E:\TEST>db2set DB2_LOAD_COPY_NO_OVERRIDE=NONRECOVERABLE
E:\TEST>db2 terminate
E:\TEST>db2set
DB2_LOAD_COPY_NO_OVERRIDE=NONRECOVERABLE
:

E:\TEST>db2 load from staff.del of del insert into staff
SQL27966W DB2_LOAD_COPY_NO_OVERRIDE 注册表变量?"NONRECOVERABLE" 覆盖在Load 中指定的 COPY NO 参数?br /> :
:


通过上述?LOAD ?COPY NOQCOPY YES ?NONRECOVERABLE 参数Q以?DB2 注册表变?DB2_LOAD_COPY_NO_OVERRIDE 的详l和举例说明Q到此我们已l掌握了它们的功能和使用Ҏ(gu)。由?LOAD 操作几乎不记日志的特性,在对启用了前滚恢复的数据库实?LOAD 操作时应注意从中选择适当的选项Q以保证执行?LOAD 操作的表的可用性?img src ="http://www.tkk7.com/anwenhao/aggbug/142912.html" width = "1" height = "1" />

]]>
解决lucene在分布式索下无法使用自定义排序规则的问题http://www.tkk7.com/anwenhao/archive/2007/08/29/140838.html安文?/dc:creator>安文?/author>Wed, 29 Aug 2007 04:03:00 GMThttp://www.tkk7.com/anwenhao/archive/2007/08/29/140838.htmlhttp://www.tkk7.com/anwenhao/comments/140838.htmlhttp://www.tkk7.com/anwenhao/archive/2007/08/29/140838.html#Feedback0http://www.tkk7.com/anwenhao/comments/commentRss/140838.htmlhttp://www.tkk7.com/anwenhao/services/trackbacks/140838.html        最q用lucene写一个多目录分布式检索的E序。不知道各位有没有遇到ParallelMultiSearcher无法使用自定排序的问题。我用indexseacher旉证我扩展的自定义排序是没有问题的。但是在ParallelMultiSearcher的情况下却始l不能按照我制定的排序规则去q行排序。郁闯极,只好跟进lucene的源码中看个I竟。发现排序没有问题。只是PriorityQueue中堆栈d我put ?pop的情况下ldoc的顺序改变了。没办法。只好自己扩展了堆栈攑օ和弹出部分代码。终于将问题解决了。下面是我修改的源码。附件上来。希望能帮助和我一样遇到问题的朋友?br>
     lucene的自定义排序Q?br>              DefaultSortImpl.java

     ParallelMultiSearcher排序修改Q?br>              ParallelMultiSearcher.java
              DefaultSortImpl.java


      

]]>
在DB2上徏立database Partition (原创)http://www.tkk7.com/anwenhao/archive/2007/08/21/138407.html安文?/dc:creator>安文?/author>Tue, 21 Aug 2007 09:03:00 GMThttp://www.tkk7.com/anwenhao/archive/2007/08/21/138407.htmlhttp://www.tkk7.com/anwenhao/comments/138407.htmlhttp://www.tkk7.com/anwenhao/archive/2007/08/21/138407.html#Feedback0http://www.tkk7.com/anwenhao/comments/commentRss/138407.htmlhttp://www.tkk7.com/anwenhao/services/trackbacks/138407.html 

database Partition Feature Q?/span>
        The Database Partitioning Feature (DPF) is a value-added option available with DB2 Enterprise 9. It extends the capability of DB2 9 into the parallel, multi-partition environment, improving performance and scalability of very large databases. This allows very complex queries to be executed much faster. DB2 Enterprise 9 with DPF is an ideal solution for managing data warehousing and data mining environments, but can also be used for large online transaction processing (OLTP) workloads.
        A database partition can be either logical or physical. Logical partitions reside on the same physical server and can take advantage of SMP architecture. Having a
partitioned database on a single machine with multiple logical nodes is know as having a shared-everything architecture, because the partitions use common memory, CPUs, disk controllers, and disks. Physical partitions consist of two or more physical servers and the database is partitioned across these servers. This is know as a shared-nothing architecture, because each partition has its own memory, CPU’s, disk controllers and disks. 

      
创徏database partition 
      1
、创建需要徏立数据库分区?/span>db instance 

       可用命令徏?/span>db instance Q?/span>

       db2icrt -s ESE -u db2admin,aaa123456 -h ANWENHAO DBINSTANCENAME

       创徏完成对应?/span>instance 后需要重?/span>DB2 .

      2、将新徏?/span>db instance 加入?/span>DB2中:(x)

CATALOG LOCAL NODE DB2INST1 INSTANCE DB2INST1 SYSTEM ANWENHAO OSTYPE NT;

       3、在命o(h)行中讄当前需要操作的dbInstance

set db2instance=db2inst1

db2 get instance

db2 attach to db2inst1

      4、创?/span>DBPartition Q?/span>

db2start dbpartitionnum 1 ADD DBPARTITIONNUM HOSTNAME ANWENHAO PORT 1 COMPUTER ANWENHAO USER db2admin PASSWORD aaa123456 WITHOUT TABLESPACES

       5、创建完成后需要重新启?/span>db2?/span>DB2在此时会(x)增加一?/span>database partition q进?/span> redistribution

       以上操作卛_?/span>database partition ?/span>

 

 

创徏database partition group :

            CREATE DATABASE PARTITION GROUP "NODE1" ON DBPARTITIONNUMS (1);
            COMMENT ON DATABASE PARTITION GROUP "NODE1" IS 'ANWENHAO _1';

 

       然后可以在徏?/span>tablespace旉择是否建立在一?/span>database partition group中。这h们就可以L使用DB2?/span>database Partition建立集群的应用了?/span>



]]>
分区表的优化{略http://www.tkk7.com/anwenhao/archive/2007/08/21/138298.html安文?/dc:creator>安文?/author>Tue, 21 Aug 2007 02:44:00 GMThttp://www.tkk7.com/anwenhao/archive/2007/08/21/138298.htmlhttp://www.tkk7.com/anwenhao/comments/138298.htmlhttp://www.tkk7.com/anwenhao/archive/2007/08/21/138298.html#Feedback0http://www.tkk7.com/anwenhao/comments/commentRss/138298.htmlhttp://www.tkk7.com/anwenhao/services/trackbacks/138298.html数据分区消除指的是数据库服务器根据查询谓词确定只需要访问表的一部分数据分区可以实现查询的能力。当对分q行决策支持查询Ӟ数据分区消除可以提供特定好处?/span>

分区表用了数据l织Ҏ(gu)Q即Q表数据Ҏ(gu)该表中一个或多个表分区键列中的值分布到多个存储对象Q称?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区或范_(d)中。根?CREATE TABLE 语句?PARTITION BY 子句中指定的内容Q给定表的数据被划分到多个存储对象中。这些存储对象可以在不同的表I间中,也可以在相同表空间中?/span>

以下CZ演示?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区消除所产生的性能斚w的好处。如果发Z下语句:(x)

CREATE TABLE custlist(subsdate DATE, Province CHAR(2), AccountID INT)
PARTITION BY RANGE(subsdate)
(STARTING FROM '1/1/1990' IN ts1,
STARTING FROM '1/1/1991' IN ts1,
STARTING FROM '1/1/1992' IN ts1,
STARTING FROM '1/1/1993' IN ts2,
STARTING FROM '1/1/1994' IN ts2,
STARTING FROM '1/1/1995' IN ts2,
STARTING FROM '1/1/1996' IN ts3,
STARTING FROM '1/1/1997' IN ts3,
STARTING FROM '1/1/1998' IN ts3,
STARTING FROM '1/1/1999' IN ts4,
STARTING FROM '1/1/2000' IN ts4,
STARTING FROM '1/1/2001' ENDING '12/31/2001' IN ts4);

假定(zhn)对 2000 q的客户信息感兴。如果发Z下查询:(x)

SELECT * FROM custlist WHERE subsdate BETWEEN '1/1/2000' AND '12/31/2000'; 

正如?101所昄的那P数据库服务器定只需要访问表I间 4Qts4Q中的一?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区可以解x查询?/span>

?101. 分区表上数据分区消除所产生的性能斚w的好?/span>
数据库服务器定只需要访问一部分数据分区可以实现查询?src="http://www.tkk7.com/images/blogjava_net/anwenhao/00022397.gif"

??102 中显C的另一?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区消除CZ是烦引扫描,它涉?qing)两个烦引ƈ?gu)以下Ҏ(gu)q行扫描Q?/span>

CREATE TABLE multi (sale_date date, region char(2))
PARTITION BY (sale_date)
(STARTING '01/01/2005' ENDING '12/31/2005' EVERY 1 MONTH);
CREATE INDEX sx ON multi(sale_date);
CREATE INDEX rx ON multi(region);

如果发出以下查询Q?/p>

SELECT * FROM multi WHERE
sale_date BETWEEN '6/1/2005' AND '7/31/2005' AND REGION = 'NW';
?102. 表分区和索引“?#8221;QANDQ的优化器决{\?/span>
比较不用表分区Q烦?#8220;?#8221;QANDQ)和用表分区Q数据分区消除)时的优化器决{\径?src="http://www.tkk7.com/images/blogjava_net/anwenhao/00022399.gif"

在不使用表分区时Q一U可能的Ҏ(gu)是烦?#8220;?#8221;QANDQ。烦?#8220;?#8221;QANDQ执行下列Q务:(x)

  • d每个索引中的所有相关烦引条?
  • 保存两组行标识(RIDQ?
  • 匚w RID 以确定哪?RID 同时出现在这两个索引?
  • 使用 RID 来访存行

?a href="http://localhost:51000/help/topic/com.ibm.db2.udb.admin.doc/doc/c0021579.htm#indexanding">?102 中所C,在用表分区的情况下Q读取烦引以查找 region ?sale_date 的匹配项Q从而允许快速检索匹配行?/p>

DB2 说明

q可以?DB2 说明来确?DB2 优化器选择的分区消除?strong>DP Elim Predicates 信息昄扫描了哪?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区来解决以下查询:(x)

 

SELECT * FROM custlist WHERE subsdate
BETWEEN '12/31/1999' AND '1/1/2001'
Arguments:
---------
DPESTFLG: (Number of data partitions accessed are Estimated)
FALSE
DPLSTPRT: (List of data partitions accessed)
9-11
DPNUMPRT: (Number of data partitions accessed)
3
DP Elim Predicates:
------------------
Range 1)
Stop  Predicate: (Q1.A <= '01/01/2001')
Start Predicate: ('12/31/1999' <= Q1.A)
Objects Used in Access Plan:
---------------------------
Schema: MRSRINI
Name: 		 CUSTLIST
Type: 		 Data Partitioned Table
Time of creation: 		 	 2005-11-30-14.21.33.857039
Last statistics update: 		 2005-11-30-14.21.34.339392
Number of columns: 		 	 3
Number of rows: 		 	 100000
Width of rows: 		 	 19
Number of buffer pool pages: 		 1200
Number of data partitions: 		 12
Distinct row values: 		 	 No
Tablespace name: 		 	 <VARIOUS>
多列支持

在用多个列作ؓ(f)表分区键的情况下Q?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区消除v作用?/span>

例如Q如果发Z下语句:(x)

CREATE TABLE sales (year INT, month INT)
PARTITION BY RANGE(year, month)
(STARTING FROM (2001, 1) ENDING AT(2001,3) IN ts1,
ENDING AT(2001,6) IN ts2,
ENDING AT(2001,9) IN ts3,
ENDING AT(2001,12) IN ts4,
ENDING AT(2002,3) IN ts5,
ENDING AT(2002,6) IN ts6,
ENDING AT(2002,9) IN ts7,
ENDING AT(2002,12) IN ts8)

接着Q发Z下查询:(x)

	SELECT * FROM sales WHERE year = 2001 AND month < 8

查询优化器推断只需要访?ts1、ts2 ?ts3 中的数据分区可以解x查询?/span>

?
在多个列l成表分区键的情况下Q只有当拥有l合键的前导列上的谓词时才能实现数据分区消除Q因为用于表分区键的非前导列不是独立的?/span>

 

多范围支?/span>

可以使用多个范围?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区上实?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区消除Q即Q一h?#8220;?#8221;QORQ运)。通过使用上一个示例中创徏的表Q执行下列查询:(x)

	SELECT * FROM sales
WHERE (year = 2001 AND month <= 3) OR (year = 2002 and month >= 10)

数据库服务器只访?2001 q的W一季度?2002 q的最后一个季度的数据?/p>

生成?/span>

可以生成列用作表分区键?/p>

例如Q可以发Z下语句:(x)

CREATE TABLE sales(a INT, b INT GENERATED ALWAYS AS (a / 5))
IN ts1,ts2,ts3,ts4,ts5,ts6,ts7,ts8,ts9,ts10
PARTITION BY RANGE(b)
(STARTING FROM (0) ENDING AT(1000) EVERY (50))

在此CZ中,生成列上的谓词用于数据分区消除。此外,当用来生成列的表辑ּ是单调的Ӟ数据库服务器?x)将源列上的谓词转换为生成列上的谓词Q从而在生成列上启用数据分区消除?/span>

例如Q如果具有以下查询:(x)

	SELECT * FROM sales WHERE a > 35

数据库服务器Ҏ(gu)Qa > 35Q在 bQb > 7Q上生成额外谓词Q从而允?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区消除?/span>

q接谓词

如果连接谓词下推到表访问别,则也可以?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区消除中用连接谓词。连接谓词仅在嵌套@环连接(NLJNQ的内部才下推到表访问别?/span>

误虑下列表:(x)

CREATE TABLE T1(A INT, B INT)
PARTITION BY RANGE(A, B)
(STARTING FROM (1, 1)
ENDING (1,10) IN ts1, ENDING (1,20) IN ts2,
ENDING (2,10) IN ts3, ENDING (2,20) IN ts4,
ENDING (3,10) IN ts5, ENDING (3,20) IN ts6,
ENDING (4,10) IN ts7, ENDING (4,20) IN ts8)
CREATE TABLE T2 (A INT, B INT)

使用的谓词有Q?

P1: T1.A = T2.A
P2: T1.B > 15

在此CZ中,׃不知道连接的外|因此不能定在~译时访问的额外数据分区。在q种情况下,以及(qing)在用主变量或参数标记的情况下,当绑定必需的值时Q就?x)发?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区消除?/span>

在运行时Q当 T1 ?NLJN 的内部表Ӟ?x)根?T2.A 的每个外值的谓词自动q行数据分区消除。在q行Ӟ对外?T2.A = 3 应用谓词 T1.A = 3 ?T1.B > 15Q这样就限定了访问的表空?ts6 ?ts7 中的数据分区?/span>

考虑?T1 ?T2 中的?A h下列|(x)

外部?T2Q列 A 内部?T1Q列 A 内部?T1Q列 B 内部?T1Q?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区位置
2 3 20 ts6
3 2 10 ts3
3 2 18 ts4
3 15 ts6
1 40 ts3

要执行嵌套@环连接(假定对内部表q行表扫描)Q数据库理器执行下列步骤:(x)

  1. d T2 中的W一行。A 的值是 2?
  2. 在连接谓?T1.A = T2.A 中将 T2.A |它是 2Q绑定到?T2.A。该谓词变?T1.A = 2?
  3. 使用谓词 T1.A = 2 ?T1.B > 15 应用数据分区消除。这限定表I间 ts4 ?ts5 中的数据分区?
  4. 在应?T1.A = 2 ?T1.B > 15 之后Q扫描表 T1 的表I间 ts4 ?ts5 中的数据分区Q直到找C行ؓ(f)止。找到的W一个合D?T1 的行 3?
  5. q接匚w的行?
  6. 扫描?T1 的表I间 ts4 ?ts5 中的数据分区Q直到找C一个匹配项QT1.A = 2 ?T1.B > 15Qؓ(f)止。再也找不到其他行?
  7. ?T2 的下一行(?A 的值替换ؓ(f) 3Q重复步?1 ?6Q直到用?T2 中的所有行为止?/li>


]]>
DB2 中用table Partition(原创)http://www.tkk7.com/anwenhao/archive/2007/08/21/138291.html安文?/dc:creator>安文?/author>Tue, 21 Aug 2007 02:27:00 GMThttp://www.tkk7.com/anwenhao/archive/2007/08/21/138291.htmlhttp://www.tkk7.com/anwenhao/comments/138291.htmlhttp://www.tkk7.com/anwenhao/archive/2007/08/21/138291.html#Feedback0http://www.tkk7.com/anwenhao/comments/commentRss/138291.htmlhttp://www.tkk7.com/anwenhao/services/trackbacks/138291.html 创徏DB Partition Group Q?br>
   CREATE DATABASE PARTITION GROUP "PG2" ON DBPARTITIONNUMS (2);
   COMMENT ON DATABASE PARTITION GROUP "PG2" IS 'PG2';

1?nbsp;在创?/span>table时可以选择table Partition 需要先创徏对应的表I间。后指定table Partition的范_(d)(x)

CONNECT TO TESTDPF;

CREATE TABLE WANGDH.TABLEPARTITIONTEST ( ID INTEGER NOT NULL , TEST BIGINT NOT NULL , CONSTRAINT CC1187661638203 PRIMARY KEY ( ID) ) PARTITION BY RANGE (ID NULLS LAST) (PARTITION PAR1 STARTING FROM (0) INCLUSIVE ENDING AT (10) INCLUSIVE IN PARTITION1 ) IN PARTITION1 CYCLE ;

CONNECT RESET;

 

2?nbsp;q加table partition 旉要先建立table space 。然后再在对应的table space 上徏?/span>partition

 

一?span>    建立table space Q?/span>

create large tablespace par2 pagesize 4K managed by automatic storage extentsize 16 overhead 10.5 prefetchsize 16;

 

NodeQ?/span>

       创徏?/span>table space 需要选择cd为:(x)large Q大型)

二?span>    使用add table partition 增加table partition:

alter table tablepartitiontest add partition PAR2 starting from (11) inclusive ending at (20) exclusive in PAR2

 

       可选择partition的范围?/span>Inclusive Q包?/span> exclusiveQ不包含

 

 

通过以上两种方式可在table层面上徏?/span>table partition 从而达到数据库中数据隔ȝ要求?/span>



]]>
客户端调用BPEL程的几U方??http://www.tkk7.com/anwenhao/archive/2007/06/25/126133.html安文?/dc:creator>安文?/author>Mon, 25 Jun 2007 08:12:00 GMThttp://www.tkk7.com/anwenhao/archive/2007/06/25/126133.htmlhttp://www.tkk7.com/anwenhao/comments/126133.htmlhttp://www.tkk7.com/anwenhao/archive/2007/06/25/126133.html#Feedback1http://www.tkk7.com/anwenhao/comments/commentRss/126133.htmlhttp://www.tkk7.com/anwenhao/services/trackbacks/126133.html使用WID开发B(ti)PEL业务程模版后,通常部v到WPS上面以后我们需要能够trgger程启动和流E运转。否则流E就没有意义了?br>
     请参考:(x)http://www.ibm.com/developerworks/cn/websphere/library/techarticles/0512_fanggw/#N100F6

q里介绍客户端调用流E的几种方式。通常有三U方式:(x)
                  1、基于服务组件架构(SCAQ的调用方式

                  2、基于Web服务的调用方?QWebService调用Q?br>                  3、通过BPC的应用程序接?br>用到最多的q是W三U通过BPC应用E序接口调用的方式。下面介l一下通过BPC应用E序调用BPEL的方式:(x)
      当我们设计好业务程。ƈ且部|到WPS下后Q?br>       我们首先要通过JNDI扑ֈLocalBusinessFlowManagerHomeQ然后生成相应的LocalBusinessFlowManager。这部分的代码片断如下:(x)
        InitialContext ctx = new InitialContext();
        LocalBusinessFlowManagerHome mgrHome =
        (LocalBusinessFlowManagerHome)ctx.lookup("java:comp/env/ejb/LocalBusinessFlowManagerHome");
        LocalBusinessFlowManager mgr = mgrHome.create();

      

调用程的代码是通过LocalBusinessFlowManager的callҎ(gu)。方法的单说明如下:(x)

public ClientObjectWrapper call(java.lang.String processTemplateName,
ClientObjectWrapper inputMessage)Q?/pre>

因此Q我们需要构Z个代表输入参数的ClientOjbectWrapper。生成一个代表输入参数的ClientObjectWrapper有多U方式,q里采用先构Z个DataObjectQ然后调用ClientObjectWrapper构造方法的方式。具体代码实现如下:(x)



ServiceManager serviceMgr = new ServiceManager();
            BOFactory bofactory = (BOFactory)serviceMgr.locateService("com/ibm/websphere/bo/BOFactory");
            DataObject input = bofactory.createByElement("http://HelloWorld/HelloWorldInterface", "hello");
            input.setString("helloInput", msg);
            ClientObjectWrapper inputWrapper = new ClientObjectWrapper(input);
            

BOFactory的createByElementҎ(gu)程的WSDL接口生成一个代表参数的一个DataObject。在生成代表输入的ClientObjectWrapper之后Q调用流E就变得相对比较单,具体代码片断如下Q?/p>

ClientObjectWrapper outputWrapper = mgr.call("HelloWorldProcess", inputWrapper);
            DataObject output = (DataObject) outputWrapper.getObject();
            resp = output.getString("helloOutput");
            



]]> վ֩ģ壺 ѳ˸Ƶ| ߹ۿëƬ| Ʒ޾Ʒպͼ| Ļ޾ƷԴ| AvƷþ| Ƶ߹ۿַ| պѹۿһ| Ʒһ24Ƶ| 88xxѹۿ| ŷa߹ۿ| ձĻ| 91۲ݹ߹ۿ| η츾AAAAƬѿ| þþþþþ91Ʒѹۿ| Ůڵվ| Ƶѹۿ| ۺ޹һҳ| ˳þõӰվ| Ůۺһ| һҹɫ| Ƶѿ| þAV| ŷxƵ| hƵѸ߹ۿ| Ƶ| ëƬѹۿȫ| ƷרëƬ| þþþùƷ| vavaպ߹ۿ| ˳ɵӰվƷ| ޾Ʒa| AV볱߹ۿ | ߹ۿ91Ʒ| 㽶Ʒ鶹| ޹㽶| ˳վ߲| ƷۺϾþ| vƵ߹ۿ| ߿Ƭ˳Ƶ| ƷƵһ| ŮaƵ|