【深入理解java虚拟机】第0集 深入理解java虚拟机

    最近看了一遍《深入理解java虚拟机》,深刻体会到理论知识的重要性,也深刻的体会到系统学习的重要性。理论指导行动,没有理论那只能是盲人摸象,很难得其要领。好记性不如烂笔头,那在学习第二遍的时候写下此系列博客,以供日后复习。

   JVM全称是java virtual machine:java 虚拟 机器;jvm的工作就是把class的字节码翻译成10101000的机器码,然后在物理机器上运行。这里面有一大部分是解释器,编译器和虚拟机计数器的功劳。

      文件格式的转换 :xxx.java  -->xxx.class(内存/磁盘/数据库/网络)  -->1010000(内存);java是解释性语言,在不同的机器上不同的JVM上被解释成不同的机器码,实现了跨平台的特性。但是为了不同平台上的本地机器码运行的结果保证一致,JVM规定了不同的JVM实现要保持一致的内存模型,保持一致的数据类型长度,保持一致的字节码执行顺序。那么不管在什么机器上,同样的代码才能保证输出的结果相同。

      当然,在不同的机器,不同的JVM中字节码可能执行的顺序不一样(可能是JVM的热编译造成的代码优化),但是根据JVM的happens-before原则,在数据使用之前,会先执行数据的相关操作,这个原则保证我们的代码会正确执行(正确的意义指的是机器输出的结果等于我们逻辑语义输出的结果)。在单线程的时候,我们不必太过于担心代码执行顺序,其实在多线程中,如果线程之前没有线程交互,资源争用,我们也不必太担心代码的执行顺序。但是在线程交互和资源争用的时候,我们一定要保证代码的先后执行顺序,且保证线程争用的数据改动能及时被其他线程看见。这个时候我们必须处理线程的并发。

线程并发时要保证结果正确,那必须要保证三大特性:原子性,顺序性,可见性。

原子性:保证多个操作结果执行的结果一致,既:同时成功,或者同时失败,例子:账户转账

顺序性:保证代码的执行顺序按照java代码规定顺序,不会被指令重排序

可见性:数据的改动应该能被下一个使用者及时发现,不会使用旧数据

其实上面的三个特性也用在事务处理。JVM中使用锁来保证三大特性,volatile只能保证一个数据的 原子性和可见性,但是不能保证顺序性。

JVM在执行代码时会不断加载class文件进入内存,解释成字节码,这个过程统称为加载-链接-初始化。加载就是class文件从内存外加载进JVM内存。链接分为三步:验证-准备-解析,验证:主要验证魔数,编译版本,准备就是为静态变量分配存储空间,初始化默认值,解析:把符号引用替换成实际引用。这个时候我们的.class已经被分配到JVM的方法区,生成了Class对象。初始化的时候就是我们代码中的new或者是反射生成对象,调用方法生成堆上的对象。

但是对象有新增就会有回收,JVM的垃圾回收方法会把过期的对象所占用的内存回收,过期的判定方法可达性分析算法,具体就是是GC Root没有索引路径可达a对象,那我们就说a对象过期,不同的JVM垃圾回收方法有不同的垃圾回收方式:单线程,多线程,分代,分区。

另外:JVM书中还讲了一部分关于java增强性能的方法,毕竟很多人说java执行速度比不上C++让jvm的开发人员很不服气,java性能增强有一部分是字节码增强,大部分是运用JVM注解对类生成字节码实现一些业务开发外的工作。

JVM有很多知识,这篇文章只是一个简单的介绍,在接下来的时间里,我会一一记录下来,希望大家指正。

你可能感兴趣的:(java,内存模型,jvm,深入理解,并发,编程)