一个java程序运行是由源码编译成.class字节码文件(严格按照虚拟机规范的一种格式),中间无任何分隔符,文件开头有一个0xcafebabe(16进制)的标志,专门用来给jvm读的。

   首先由.java的源代码 编译成.class字节码,然后被加载到JVM,JVM会为class分配一个区域,也就是JVM运行时数据区。

java如何开启共享线程变量的线程_java如何开启共享线程变量的线程

1.区域中 分为线程共享区域和线程独占部分:

1.1 线程独占:每个线程都会有它独立的空间,随线程生命周期而创建和销毁(线程在创建时,会在虚拟机栈,本地方法栈,程序计数器中开辟一块独占的空间)。

1.2 线程共享:所有的线程都能访问这块内存数据,随虚拟机或者GC而创建和销毁(堆内存)。

2.线程共享部分:

2.1 方法区:存class的信息,常量,静态变量,编译后的代码。(虚拟机规范中这是一个逻辑区划,根据不同虚拟机来实现。如oracle的HotSpot在java7中方法区放在永久代,java8放在元数据空间,并通过GC机制对这个区域进行管理)

2.2 堆内存:存放对象的区域(堆内存还可以细分为:老年代,新生代(Eden. From Survivor. To Survivor), JVM启动时创建,存放对象的实例。垃圾回收器主要就是管理堆内存,如果满了就会出现OutofMemroyError )

3.线程独占部分

3.1 虚拟机栈 : 每个线程都在这个空间有一个私有的空间。线程栈由多个栈帧(Stack Frame)组成。一个线程会执行一个或多个方法,一个方法对应一个栈帧,栈帧内容包含:局部变量表,操作数栈,动态链接,方法返回地址,附加信息等。栈内存默认最大是1M,超出则抛出StackOverflowError )  

3.2 本地方法栈 : 和虚拟机栈功能类似,虚拟机栈是为虚拟机执行JAVA方法而准备的,本地方法栈是为虚拟机Native本地方法而准备的。虚拟机规范没有规定具体的实现,由不同的虚拟机厂商去实现。HotSpot虚拟机中虚拟机栈和本地方法栈的实现是一样的。同样,超出大小后也会抛出StackOverflowError

3.3 程序计数器(Program Counter Register):好比是代码执行的位置,记录当前线程执行字节码的位置,存储的是字节码指令地址,如果执行Native 方法,则计数器值为空。

 

注:

1.每个线程都在这个空间有一个私有的空间,占用内存空间很少。

2.Cpu同一时间,只会执行一条线程中的指令。JVM多线程会轮流切换并分配CPU执行时间的方式。为了线程切换后,需要通过程序计数器,来恢复正确的执行位置。

3.JVM怎么处理新方法?

JVM会根据这个方法描述,创建新栈帧,方法中的参数从操作数栈中弹出来,压入虚拟机栈,然后虚拟机会开始执行虚拟机栈最上面的栈帧