您的位置:首页 > 其它

jvm基础结构

2017-09-25 12:07 267 查看


PC寄存器

每个线程拥有一个PC寄存器

在线程创建时 创建

指向下一条指令的地址

执行本地方法时,PC的值为undefined

方法区

保存装载的类信息

类型的常量池

字段,方法信息

方法字节码

通常和永久区(Perm)关联在一起

Java堆

和程序开发密切相关

应用系统对象都保存在Java堆中

所有线程共享Java堆

对分代GC来说,堆也是分代的

GC的主要工作区间

Java栈

线程私有

栈由一系列帧组成(因此Java栈也叫做帧栈)

帧保存一个方法的局部变量、操作数栈、常量池指针

每一次方法调用创建一个帧,并压栈

Java栈 – 操作数栈

Java没有寄存器,所有参数传递使用操作数栈



Java栈 – 栈上分配

小对象(一般几十个bytes),在没有逃逸的情况下,可以直接分配在栈上

直接分配在栈上,可以自动回收,减轻GC压力

大对象或者逃逸对象无法栈上分配



public   class  AppMain
//运行时, jvm 把appmain的信息都放入方法区
{
public   static   void  main(String[] args)
{ Sample test1 = new  Sample( " 测试1 " );
//test1是引用,所以放到栈区里, Sample是自定义对象应该放到堆里面 Sample test2 = new  Sample( " 测试2 " );
test1.printName();
test2.printName(); }
public   class  Sample
//运行时, jvm 把appmain的信息都放入方法区
{ private  name;
//new Sample实例后, name 引用放入栈区里,  name 对象放入堆里 public  Sample(String name)
{ this .name = name; }
public   void  printName()
{ System.out.println(name); } }


内存模型

每一个线程有一个工作内存和主存独立

工作内存存放主存中变量的值的拷贝

当数据从主内存复制到工作存储时,必须出现两个动作:第一,由主内存执行的读(read)操作;第二,由工作内存执行的相应的load操作;当数据从工作内存拷贝到主内存时,也出现两个操作:第一个,由工作内存执行的存储(store)操作;第二,由主内存执行的相应的写(write)操作

每一个操作都是原子的,即执行期间不会被中断

对于普通变量,一个线程中更新的值,不能马上反应在其他变量中

如果需要在其他线程中立即可见,需要使用 volatile 关键字



public class VolatileStopThread extends Thread{
private volatile boolean stop = false;
public void stopMe(){
stop=true;
}

public void run(){
int i=0;
while(!stop){
i++;
}
System.out.println("Stop thread");
}

public static void main(String args[]) throws InterruptedException{
VolatileStopThread t=new VolatileStopThread();
t.start();
Thread.sleep(1000);
t.stopMe();
Thread.sleep(1000);
}
//volatile 不能代替锁
一般认为volatile 比锁性能好(不绝对)

选择使用volatile的条件是:
语义是否满足应用


可见性

一个线程修改了变量,其他线程可以立即知道

保证可见性的方法

volatile

synchronized (unlock之前,写变量值回主存)

final(一旦初始化完成,其他线程就可见)

解释运行

解释执行以解释方式运行字节码

解释执行的意思是:读一句执行一句

编译运行(JIT)

将字节码编译成机器码

直接执行机器码

运行时编译

编译后性能有数量级的提升
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: