Month: September 2011

五种线程状态的精确定义

摘自《深入理解Java虚拟机》周志明著 1. New: 创建后尚未启动 2. Runnable: Running(正在执行) 或 Ready(正在等待分配时间片) 3. Waiting: 不会分配CPU时间,直到被唤醒进入Runnable 4. Timed Waiting: 不会分配CPU时间片,直到被唤醒,或者Time Up 5. Blocked: 在等待一个排它锁,等拿到锁了就进入Runnable

学习JVM原理-19.Java内存模型与并发

摘自《深入理解Java虚拟机》周志明著 JMM(Java Memory Model)是一种统一的内存模型,它屏蔽了各种硬件和操作系统的内存访问差异 它规定:   1. 所有变量都存储在Main Memory中   2. 每条线程有自己的Working Memory,里面存有Main Memory变量的副本; 线程只能操作这些副本,不能直接操纵Main Memory里的变量 JMM下的并发过程中有3个问题: Atomicity, Visibility, Ordering   1. Atomicity: 基本数据类型的读写基本上是原子的;另外可以通过synchornized加锁保证原子性   2. Visibility: 指变量被一个线程修改后能立即被另一个线程看到。volatile可以实现visibility, 因为用volatile的变量被线程修改后会立即同步到Main Memory中; synchronized关键一般也可以,因为它规定“对一个变量Unlock之前,必须先把变量同步回Main Memory”中   3. Ordering: JVM会对指令进行重排,后面的代码可能会在前面的代码之前执行。Ordering的意思是,不管指令重排成什么样,最终的结果不受影响。 volatile可以实现ordering,因为它禁止了指令重排; synchronized关键字也可以,因为它通过锁机制保证了线程对同一个资源进行访问的串行性

收藏一本书:《深入理解计算机系统》

原名叫: Computer Systems, a programmer’s perspective 应该在译名前加一个 “从程序员的角度” http://book.douban.com/subject/1230413/ 前言节选 3 preface 7 about the authors 21 1 a tour of computer systems 35 1.1 information is bits + context 37 1.2 programs are translated by other programs into different forms 38 1.3 it pays to understand how compilation systems work 40 1.4 processors read and interpret …

收藏一本书:《深入理解计算机系统》 Read More »

学习JVM原理-18.Java比C/C++的性能倒底差在哪里?

摘自《深入理解Java虚拟机》周志明著 都说因为解释执行的缘故,JAVA比C/C++差; 现在主流JVM都带JIT编译器了,JAVA还比C/C++差吗?  答案:是。缺点如下:   1.JIT是在运行时编译,占用系统开销,挤占了程序本身的资源     2.JVM需要检查空指针、指针越界等问题,耗时     3.JAVA里多态用的更多,很多virtual方法,编译时不好做内联优化     4.JAVA可以动态加载类,改变程序的继承关系,这使得很多全局优化都不好做     5.JAVA在栈上还是堆上分配内存这个机制是固定的,C/C++就灵活多了,可以按需分配,实现更好的性能     6.JAVA要GC,GC耗资源

学习JVM原理-16 VM Stack里的数据结构

摘自《深入理解Java虚拟机》周志明著 VM Stack是一个栈,栈里面的一个元素称作一个Stack Frame,它是用于支持虚拟机进行方法调用和方法执行的数据结构。 一个方法的执行过程,实际就是一个Frame入栈和出栈的过程 Stack Frame的组成: 1. Local Variable Table: 存放方法的局部变量 2. Operand Stacks 3. Dynamic Linking 4. Return Address

学习JVM原理-17.早期编译与运行时JIT编译

摘自《深入理解Java虚拟机》周志明著 虽有那种直接把*.java变成本地执行代码的编译器,但java的编译方式主要有两种:   1. 前期编译:即SUN的javac, 把java编译成字节码; 运行时由解释器解释执行   2. 运行时编译:JIT(Just in Time)编译器,运行时把Hot Spot(经常访问的代码)编译成本地代码执行(注意,JIT并不是JVM规范,有的JVM实现里没有JIT) Java程序运行时就是 解释器 + JIT编译器 一起工作(你可以用-Xint禁止编译器)。解释器发现HotSpot后,如果已有对应的本地代码,就会让JIT执行这段代码;否则,会一边让JIT在后台编译,一边自己解释执行。有时JIT如果发现自己不能够执行本地代码,也会把任务交给解释器 另外,两种编译器都会做些优化动作:   1.javac: 一个例子就是解除泛型这个语法糖,因为字节码是不认泛型的,List<String>在字节码里的类型就是List   2.JIT: 比如内联     

学习JVM原理-如果constant literal变了,用到它的其它类都要重新编译

假定Foo里定义了一个constant literal(literal 指String, int之类的字面量),而Bar里又用到了这个常量 一旦Foo里的常量值变了, 而Bar没有重新编译,则Bar里的值仍是Foo变之前的那个值 为什么会这样?  因为编译Bar时会把Foo里的常量值直接写到Bar.class这个字节码文件里; 运行Bar的代码时,JVM并不会动态地去Foo里取这个值,而是直接从Bar.class字节码文件中把值找出来,所以Foo的改动不会影响到Bar的运行 所以,如果Foo里的常量值变了,则Bar应该重新编译,把Foo中的新值更新到字节码文件中

两个Integer对象是否 ==

其机制与String是类似的 Integer a = 5; Integer b = 5; System.out.println(a == b); // true. Integer c = new Integer(5); Integer d = new Integer(5); System.out.println(c == d); // false.

学习JVM原理-15.类initialization与继承关系

摘自《深入理解Java虚拟机》周志明著 class Bean { static { System.out.println("Bean inited"); } } class SubBean extends Bean{ static { System.out.println("SubBean inited"); } } main(){ int i = SubBean.subBeanValue; /*会先打印"Bean inited",再打印"SubBean inited" */ /*JVM会保证在子类的<clinit>方法执行之前,父类的<clint>()方法已经执行完毕*/ }