jvm运行机制

jvm启动流程
启动java进程-》装载配置(根据当前路径和系统版本寻找jvm.cfg)-》根据配置寻找JVM.dll(JVM.dll为JVM主要实现)-》初始化JVM获得JNIEnv接口(JNIEnv为JVM 接口,findClass等操作通过它实现)-》找到main方法并运行。

jvm基本结构
这里写图片描述

PC寄存器
每个线程拥有一个PC寄存器(程序计数器)
在线程创建时 创建
指向下一条指令的地址
执行本地方法时,PC的值为undefined

方法区
保存装载的类信息
类型的常量池(JDK6时,String等常量信息置于方法JDK7时,已经移动到了堆)
字段,方法信息
方法字节码
通常和永久区(Perm)关联在一起

Java栈(包括局部变量表和操作数栈)
线程私有
栈由一系列帧组成(因此Java栈也叫做帧栈)
帧保存一个方法的局部变量、操作数栈、常量池指针
每一次方法调用创建一个帧,并压栈

Java栈 – 栈上分配实例(jvm对内存分配做了很多优化,其中一个就是将小对象直接分配到栈,我们知道,栈是非常快的)
如下的程序:
如果jvm配置为:

-server -Xmx10m -Xms10m
-XX:+DoEscapeAnalysis -XX:+PrintGC

添加逃逸分析后,则不会进行GC,因为小对象都直接分配到了栈里。

如果jvm配置为:

-server -Xmx10m -Xms10m  
-XX:-DoEscapeAnalysis -XX:+PrintGC

则会出现如下GC日志。

……
[GC 3550K->478K(10240K), 0.0000977 secs]
[GC 3550K->478K(10240K), 0.0001361 secs]
[GC 3550K->478K(10240K), 0.0000963 secs]
564
public class OnStackTest {
    public static void alloc(){
        byte[] b=new byte[2];
        b[0]=1;
    }
    public static void main(String[] args) {
        long b=System.currentTimeMillis();
        for(int i=0;i<100000000;i++){
            alloc();
        }
        long e=System.currentTimeMillis();
        System.out.println(e-b);
    }
}

Java栈 – 栈上分配
小对象(一般几十个bytes),在没有逃逸的情况下,可以直接分配在栈上
直接分配在栈上,可以自动回收,减轻GC压力
大对象或者逃逸对象无法栈上分配

内存模型
每一个线程有一个工作内存和主存独立
工作内存存放主存中变量的值的拷贝
对于普通变量,一个线程中更新的值,不能马上反应在其他变量中
如果需要在其他线程中立即可见,需要使用 volatile 关键字。

可见性
一个线程修改了变量,其他线程可以立即知道
保证可见性的方法
volatile
synchronized (unlock之前,写变量值回主存)
final(一旦初始化完成,其他线程就可见)

有序性
在本线程内,操作都是有序的
在线程外观察,操作都是无序的。(指令重排 或 主内存同步延时)

volatile规则:volatile变量的写,先发生于读
锁规则:解锁(unlock)必然发生在随后的加锁(lock)前

解释运行
解释执行以解释方式运行字节码
解释执行的意思是:读一句执行一句

编译运行(JIT)
将字节码编译成机器码
直接执行机器码
运行时编译
编译后性能有数量级的提升

java的编译器先将其编译为class文件,也就是字节码;然后将字节码交由jvm(java虚拟机)解释执行;
所以很多地方都说“java是一种半编译、半解释执行”的语言;
近来(其实也不是很”近”)Oracle的(以前是Sun的)HotSpot VM采用了jit compile(just in time compilation)技术,将运行频率很高的字节码直接编译为机器指令执行以提高性能, 所以当字节码被jit编译为机器码的时候,要说它是编译执行的也可以…
不过总体来讲,java的编译结果是被jvm“解释执行”的,所以这么说也能说通,而其实这个“是编译还是解释”这个概念在这里已经有点模糊了,理解它的过程就行了,不必下一个“精确”的定义;
而我自己仍然赞成“java是编译型语言”的说法,因为“编译”其本质就是“把一个相对高级的语言转换为另一个相对低级的语言”,而由java -> class文件的编译已经满足了这个特征; 而后面你要说jvm是“解释执行”的,那其实硬件对于机器码又何尝不是“解释执行”呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值