`
sundful
  • 浏览: 1250141 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java学习杂谈(十一)

    博客分类:
  • Java
阅读更多
本来这次应该讲讲ORM的几个框架,但是笔者还没有完全总结出来,所以这里先插入一次学习JVM的心得。作为一个Java程序员,如果不了解JVM的工作原理,就很难从底层去把握Java语言和Java程序的运作机制。这里先推荐一个最权威的讲解JVM的文档,大家只要查过Java       API的可以在里面的一个叫“API,       Language,       and       Virtual       Machine       Document”的标题下看到四个子标题,第一个是我们最熟悉的Java       API       Specification,很少会有人注意到第三和第四个子标题,分别是“The       Java       Language       Specification”和“The       Java       Machine       Specification”后面都带有(Download)字样,JVM的那个URL直接链接到http://java.sun.com/docs/books/vmspec/2nd-edition/这里地址。我们可以下载到一份非常权威详细的讲解JVM原理的官方文档。笔者业余时间花了1个星期来阅读,这里把自己的收获跟大家来分享一下,大概从这么几个方面来谈一谈:  

                1.   JVM的实现机制  
                Java虚拟机就是一个小的计算机,有自己的指令集,有自己的文件系统,管理内部的表和数据,负责读取class文件里面字节码,然后转换成不同操作系统的CPU指令,从而使得Java程序在不同的操作系统上顺利的跑起来。所以Window的JVM能把字节码转换成Window系统的指令集,Linux的JVM能把字节码转换成Linux系统的字节,同理还有Solaris,它们彼此之间是不能通用的。最早一款的原型虽然是Sun公司开发的,但发展到现在其实任何厂商都可以自己去实现一个虚拟机,用来读取字节码转换成OS指令。甚至我们可以认为JVM跟Java编程语言都没有关系,因为你自己哪怕用记事本写一串字节码,也可以让JVM来解析运行,只要你的字节码能通过JVM的验证。  

                JVM的验证其实是很严格的,这里只讲一些有趣的地方。大家还记得Java的图标是一个杯咖啡麽?究其历史我们也许可以查出为什么,但还有更显而易见的方式是JVM怎么判断一个文件是否是class文件?JVM的做法是读取前4个字节转换成16进制数,判断是否等于0xCAFEBABE这个数。注意到这个单词了麽?“cafebabe”,代表着国外一种咖啡品牌,似乎叫做Peet’s       coffee-baristas之类。创造Java的人为了方便记忆,选择了这样一个16进制数作为标准class文件的头,所以任何class文件都必须具有这4个字节的头部。我们可以用DataInput这个接口的实现类来验证一下,读取任何一个class文件的第一个int,int在Java里面是四个字节。转换成16进制一定会是0xcafebabe的。  
                所以这里想告诉大家的是,JVM其实并没有那么神秘,我们完全可以理解它的构造。  

                2.   Java相关的基础概念  
                配合JVM的结构,在Java语言中也会有很多特点比较鲜明的地方。比如对数值计算从来不会检查位溢出。任何变量存储的二进制即使位全部为1了仍然可以加,全部为0了仍然可以减。大家只要稍微测试一下就知道了,看这几个例子:  
                int       max       =       Integer.MAX_VALUE;  
                int       min       =       Integer.MIN_VALUE;  
                max+1       ==       min;   //true  
                min-1       ==       max;                                   //true  
                0.0/0.0   //得到“NaN”(Not       a       number)  
                1/0.0   //Infinity  
                -1/0.0                                                                       //-Infinity  
                1或-1/0   //ArithmeticException唯一的异常情况  

                看完这几个例子,大家是否能更好的把握Java的数值运算呢?Java完全遵照IEEE-754的标准来定义单双精度浮点数以及其他的数值存储方式。  
               
                另外Java里面有一个概念叫做Daemon       Thread(守护线程),知道它的存在主要是为了理解虚拟机的生命周期。当我们运行java命令,从main函数进入的那一刻起,虚拟机就开始启动运行了。Main所在的主线程也会启动起来,它属于非守护线程。与之同时一些守护线程也会同时启动,最典型的守护线程代表就是GC(垃圾收集器)线程。JVM虚拟机什么时候退出呢?是在所有的非守护线程结束的那一刻,JVM就exit。注意这个时候守护线程并未退出,很可能还要继续完成它的本职工作之后才会结束,但虚拟机的生命周期已经提前于它结束了。  

                3.   JVM内部的基本概念  
                虚拟机内部还有一些概念,全部列举是不现实的,太繁琐也没有意义。除非您真的想自己去做一个JVM。笔者只列举部分概念:  
                首先我们来看一个叫做ReturnAddress的变量,它是JVM用来存储方法出口或者说进行跳转的依据,把任何地址存入这个变量就一定会按照这个地址来跳转。我们需要注意的就是finally有比方法return更高的赋值给ReturnAddress的优先级。同时存在方法return和finally       return的话,一定是按照finally里面的return为准。  
               
                JVM有自己的Heap,能被所有线程共享,存储着所有的对象,内存是动态被分配的。对于每个线程,拥有自己的Stack,栈里面存储的单位叫做Frame(桢)。桢里面就记录着零时变量、对象引用地址、方法返回值等数据。JVM还有一个叫做Method       Area的地方,存储着一段一段的可执行代码,每一段就是一个方法体,也能被所有线程共享。所以我们说一个线程其实从run方法跑起来,跟它的类中声明的其他方法是两个概念。因为其他的方法包括的所有的对象,这个时候都充当为资源被线程使用。  

                JVM有自己管理内存的方案,因为它具有文件系统的功能,我们可以看成一个小型的数据库,内部有许许多多不同的表。表的字段可能是另外一张表的地址,也可以直接就是一个存储数据值的地址值。JVM所有对运行时候类的解析验证计算等管理工作,实际上都是在管理这些表的变动,如果我们从数据库的角度来看,JVM所做的就是根据你的代码来操作那么多个表最后返回给你结果的过程。里面的表结构包括class的表、field表、method表、attribute表等。  

                4.   JVM的指令集  
                JVM有自己的指令集,笔者从前也看过一些计算机组成结构和汇编语言的数,建议大家也稍微看看,了解设计一个高效可用的计算机指令集是多么复杂又多么重要的过程。对于JVM的指令集,职责是管理好Java程序编译出来的字节码,相对而言指令集的名称就多少和Java语言相关了,比如指令集里就有sastore,、saload表示array里面short的存和取、类似还有d2i表示从double转换成int、monitorenter表示进入synchronized块加锁、getstatic和putstatic表示对静态标量的存取、       jsr和ret等跳转指令……  

                为了便于记忆,设计JVM指令集的人们约定f开头的跟float有关,d跟double有关,i跟int有关,s跟short有关,a跟array有关。有兴趣的可以细读文档里面的每一个指令的作用。因为只是作为初步了解,这里就不多说了。  

                5.   一些Java关键字的实现原理  
                文档还很详细的列举了很多加载、初始化、加锁等操作的过程。笔者觉得比较有用的第一是记住Java里面只有Array不是由ClassLoader加载的对象,其他的对象全部都必须由一个ClassLoader来加载。另外package的概念除了类似于C++的namespace,是一种命名空间之外,底层的实现是规定同一个package下的类必须由同一个类加载器来加载,所以package的概念还可以认为是被同一个类加载器加载的类。  
               
                另外在多线程中,有很多细节值得去体会。每个线程有自己的Working       memory,它们从能被共享的Main       Memory中去读数据、修改、然后再存回去。笔者一直认为线程就是数据库里面事务的前身或者说祖先。我们只要稍微比较一下它们的行为,就会发现很多一致性。事务也是操作被事务共享的表数据,你改完我改,顺序不一致就会出现脏数据,而线程同样会出现脏数据。我们对线程加的锁策略,同样在事务中也有适用。当然多事务的情况显然比多线程更加复杂,但我们只要理解了多线程,相信对学习数据库事务的效果也是非常有帮助的。Java里面除了synchronized能够帮助同步多线程之外,还有一个弱同步的操作关键字是volatile,它产生在变量上的约束在文档中也有详细的说明。因为很复杂,考虑到篇幅笔者就不打算解释一遍了。  

                好了,又是新的一篇结束了。大概再有一两篇笔者大学关于Java所学就差不多说完了。不足之处大家尽管提出来,笔者愿意接受各种职责批评,因为笔者认为失败的教训往往比成功更加助人成长。这个帖子一直以来得到那么多朋友的大力支持和鼓励,笔者在这里真诚的说一声谢谢!因为笔者即将毕业投入茫茫人海去从草根阶层开始挣扎,最近冷静的想了很多,即使毕业了,要提高的不止是技术,还包括很多综合素质,也许并不能马上找到如意的团队和工作岗位,只能承认自己是弱势群体,有时不得不向现实的生活低头,不知道今后是否还有这闲心去写学习笔记,去坚持走分享的道路。其实很多人我认为也很有心去分享,但被现实的生活束缚了手脚。所以也期望还呆在学校里的大学生们好好努力的珍惜那份无忧虑的心境和安静的环境,好好充实自己吧!
分享到:
评论

相关推荐

    Java学习杂谈1-12

    Java学习杂谈系列涵盖了许多关于Java编程的基础概念和机制,以下是对这些知识点的详细解读: 1. **动态加载机制**: 动态加载机制是Java语言的一个关键特性,它使得程序在运行时才能确定哪些类需要加载。当你声明...

    java学习杂谈

    ### Java学习杂谈:深入解析Java的动态加载机制、类搜索原理及JDK与JRE的区别 #### 动态加载机制解析 Java的学习者往往在掌握面向对象编程(OOP)概念时,会遇到“动态加载机制”这一关键点。相较于C++中面向过程...

    主流编程语言的选择和学习杂谈

    "主流编程语言的选择和学习杂谈" 本文主要介绍了当前主流编程语言的特点、发展趋势和学习方法,为新手提供了学习参考。 一、Java 语言 Java 语言是由 Sun 公司开发的,目前由 Java Community Process 控制。Java ...

    2009年Java认证考试重点指导

    [学习资料] 09年Java认证考试:我的Java学习道路 [学习资料] 09年Java认证考试:学好java开发的关键七步 [学习资料] 09年Java认证考试:JAVA求素数算法实现 [学习资料] 09年Java认证考试:java类的构造方法 [学习...

    java杂谈-一个计算机专业学生几年的编程经验汇总谈.pdf

    此外,随着Java版本的更新,一些机制可能会有所变化,例如类加载器的工作方式在JDK 1.4到1.6之间可能有所调整,因此持续学习和跟踪Java的最新发展也是必要的。 总之,Java的动态加载机制、类加载器的工作原理以及...

    程序设计经验杂谈,程序设计,经验杂谈

    例如,Python有PEP 8,Java有Google Java Style Guide,这些都是值得遵循的编码规范。 最后,项目管理在大型项目中扮演着重要角色。了解敏捷开发理念,如Scrum或Kanban,可以帮助团队有效地组织和管理任务。同时,...

    java陈国君(第二版)课件

    总的来说,《Java陈国君(第二版)课件》是一个全面的Java学习资源,无论你是零基础的新手,还是希望进一步提升的开发者,都能从中受益匪浅。通过深入学习和实践,你将能够掌握Java编程的核心技能,为未来的编程生涯...

    java_学习资料

    ### Java框架知识学习 #### Struts 1.x **手写MVC框架** - **概念理解**:在探讨Struts框架之前,先了解MVC(Model-View-Controller)架构模式的基本原理。这是一种广泛应用于软件工程的设计模式,尤其是用于Web...

    臧圩人--JAVA面试题解惑系列合集.pdf

    **1.6 JAVA面试题解惑系列(六)——字符串(String)杂谈** - **知识点**:深入探讨字符串处理技术,包括字符串拼接、比较、格式化等常见操作的内部实现,以及性能优化建议。 **1.7 JAVA面试题解惑系列(七)——...

    组建java团队.pdf

    - 发布工具:Jenkins是自动发布工具的首选,它既关乎管理人员的经验,也关系到开发人员的学习与适应能力。Jenkins能够在持续集成中发挥关键作用,提高软件交付的速度和质量。 - Bug管理:合理的Bug管理能够确保软件...

    Java面试题详解,和一些基础知识的深入剖析,个人认为非常棒

    “JAVA面试题解惑系列(六)——字符串(String)杂谈”可能涉及到String池的概念,即JVM会缓存重复的字符串,以提高性能。此外,String的equals()和==的区别也常常是面试的焦点,前者比较内容,后者比较对象引用。 ...

    JAVA面试题解惑系列

    【JAVA面试题解惑系列】是一系列专门...以上只是《JAVA面试题解惑系列》中部分主题的简要介绍,每篇文章都深入探讨了相关主题,为面试者提供了丰富的学习资料。掌握这些知识点,将有助于在面试中表现出扎实的Java基础。

    程序设计经验杂谈

    C++或Java则适合深入理解面向对象编程。 3. **算法与数据结构**:程序设计的核心是解决问题,这往往涉及算法的选择和应用。基础算法如排序(冒泡、快速、归并)、查找(线性、二分)以及递归等,是每个程序员必备的...

    j2ee杂谈

    在IT行业中,J2EE(Java 2 Platform, Enterprise Edition)是一个广泛使用的开源企业级应用开发平台,由Oracle...通过深入学习和实践这两个技术,开发者可以更好地应对复杂的业务场景,打造健壮、可维护的Java应用。

    android开发杂谈

    这篇"Android开发杂谈"涵盖了从系统组成、启动过程到关键组件的解析,旨在为初学者提供一个全面的理解框架。 Android系统是由多个层次构成的,包括Application、Framework、Native Libraries、Userspace Drivers...

    swing开发杂谈--初版本程序源码

    Swing是Java编程语言中用于构建图形用户界面(GUI)的一个工具包,它是Java Foundation Classes ...通过学习和理解这个初版本的源码,开发者能够更好地掌握Swing的使用,并在此基础上构建更复杂的Java GUI应用程序。

    JAVA数据结构和算法

    深入浅出 例子实用 代码丰富 是java程序人员学习和深入数据结构和算法的实用读物 由于资源过大,分两部分上传 本资源为第二部分

    java俄罗斯方块

    综上所述,“java俄罗斯方块”项目涵盖了Java编程中的许多核心概念和技术,是学习和实践Java GUI编程、多线程、游戏开发和数据处理的绝佳案例。通过这个项目,开发者不仅可以掌握Java编程基础,还能深入理解游戏开发...

Global site tag (gtag.js) - Google Analytics