深入java虚拟机系列之JMM布局篇(一)

Sun(Oracle) 发起了Coin子项目来统一处理对java语法的细节修改,如二进制数的原生支持、在switch语句中支持字符串、”<>”操作符、异常处理的改进、简化变长参数方法调用、面向资源的try-catch-finally语句等都是在Coin项目之中提交的内容。另外,JSR-335中定义的Lambda表达式也将对java 的语法和语言习惯产生很大的影响,函数式编程可能会成为主流。 JDK7源码下载地址:http://download.java.net/openjdk/jdk7/


深入java虚拟机系列之JMM布局篇(一)_第1张图片
 

 

JVM内存总的来分有线程私有和公有

程序计数器:用作当前线程所执行的字节码的行号指示器。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。

Java虚拟机栈:每个方法被执行的时候都会同时创建一个栈帧用于存储局部变量表、操作栈、动态链接、方法出口等信息。局部变量表存放了编译器可知的各种基本数据类型、对象引用类型和returnAddress类型,所需的内存空间在编译期间完成分配。规定了两种异常情况:1. 线程请求的栈深度大于虚拟机所允许的深度,抛出StackOverflowError2. 如果虚拟机栈可以动态扩展,当扩展时无法申请到足够的内存时会抛出OutOfMemoryError异常(OOM)。

本地方法栈Sun HotSpot直接把本地方法栈和虚拟机栈合二为一。

Java:存放对象实例。虚拟机规范:所有的对象实例以及数组都要在堆上分配,但是随着JIT编译器的发展与逃逸分析技术的逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化发生,所有的对象都分配在堆上也渐渐的变得不是那么绝对了。

方法区:与java堆一样,是各个线程共享的内存区域,用于存放已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

运行时常量池:方法区的一部分。用于存放编译器生成的各种字面量和符号引用,不要求常量一定只能在编译器产生,比较典型的是String类的intern()方法,这部分内容将在类加载后存放到方法区的运行时常量池中,还会把翻译出来的直接引用也存储在运行时常量池中。Class文件中除了有类的版本、字段、方法、接口等描述等信息外(Class文件常量池),还有一项信息是常量池。

直接内存:操作系统内存,优点是在某些场景下无需在java堆和Native堆(应该说的是操作系统内存)中来回复制数据。

对象访问:主流的访问方式有两种:使用句柄和直接指针。

1.使用句柄

深入java虚拟机系列之JMM布局篇(一)_第2张图片

优点:在对象被移动时只会改变句柄中的实例数据指针,而reference本身不需要被修改。

缺点:多一次指针定位。

 2.直接指针


深入java虚拟机系列之JMM布局篇(一)_第3张图片
 

 

 

优点:速度更快,节省了一次指针定位的时间开销。

缺点:需要修改reference

Sun HotSpot使用了直接指针的方式。

这里也涉及到软件设计中的思想,要根据实际情况来设计。比如说对象移动是否频繁等因素来考虑设计方案。

 

 

你可能感兴趣的:(深入java虚拟机系列之JMM布局篇(一))