您的位置:首页 > 其它

jvm内存模型

2015-04-30 12:36 218 查看
Java虚拟机运行时会把它所管理的内存分为如下几个数据区域:



1.程序计数器,线程私有,用做当前线程所执行的字节码的行号指示器,字节码解释其通过改变这个计数器的值开获取下一条需要执行的字节码指令,每条线程都有一个独立的计数器。

2.Java虚拟机栈,线程私有,描述的是java方法执行的内存模型,每个方法执行时都会创建一个栈帧,存储局部变量表,操作栈,动态链接,方法出口等信息。如果线程请求的栈深度大于虚拟机所允许的深度则抛出stackOverflowError异常;若虚拟机可以动态扩展,当扩展时无法申请到足够的内存时会抛出OutOfMemoryError异常

3.本地方法栈,线程私有,为虚拟机使用到的Natice方法服务。

4.Java堆,线程共享,在虚拟机启动时创建,存放对象实例,几乎所有对象实例都在这里分配内存,也是垃圾收集器管理的主要区域,也称为GC堆;内存空间可以物理不连续,但逻辑上连续即可;如果在堆中没有内存完成实例分配,并且堆无法再扩展时将会抛出OutOfMemoryError异常。

5.方法区,线程共享,存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据

 

JAVA程序最初是通过解释器(Interpreter)进行解释执行的,当JVM发现某个方法或代码块运行特别频繁的时候,就会认为这是“热点代码”(Hot Spot Code)。

为了提高热点代码的执行效率,就会将这些“热点代码”编译成与本地机器相关的机器码,进行各个层次的优化。 完成这个任务的编译器就是即时编译器(JIT)。在这个区域的内存回收目标主要是针对常量池的回收和对类型的卸载;当方法区无法满足内存分配需求时将抛出OutOfMemoryError异常。

5.1运行时常量池,用于存放编译期生成的各种字面量和符号引用;具有动态性,并非预置入calss文件中常量池的内容才能进入,运行期间也可能将新的常量放入池中。如string类的intern()方法

 

intern是一个native的方法,但按照其文档解释,应该是JVM维护了一个当前进程曾经出现过的字符串的hash表,在调用intern时,会查询该表。如果已经存在,则直接返回对该String的引用;如果没有,则创建一个,并加入到hash中。

 

 

JVM的两款即时编译器JIT

JVM中默认内置了两款即时编译器,称为Client Compiler和Server Compiler。

可以用指定参数的方式,指定采用Client模式和Server模式。默认是mixed模式。

   java –Xint 解析 java –Xcomp 编译

解析器与编译器并存:

1、当程序需要迅速启动和执行的时候,解析器首先发挥作用,省去编译的时间,立即执行。随着时间的推移,编译器发挥作用,把越来越多的代码编译成本地代码,获得更高的执行效率。

2、当机器内存限制比较大,可以用解析方式节约内存,反之可以用编译提升效率。

3、解析器还可以作为编译器的“逃生门”。当例如加载了新类后类型结构发生变化,可以采用逆优化,退回到解析状态继续执行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息