写这篇文章,主要是为了记录自己复习Java虚拟机的一些心得总结笔记,仅供分享参考学习,如有不对的地方,敬请指正。
今天要是要说的是:运行时常量池(Runtime Constant Pool),直接内存(Direct Memory)。
本文中提到的字面量、符号引用、直接引用等词将在本文的后面做出解释。
1、运行时常量池
运行时常量池是方法区的一部分(关于方法区的说明,清考我我的文章Java内存区域与内存溢出异常)。它用于存放编译期生成的各种字面量和符号引用,这部分内存将在类加载后进入方法区的运行时常量池中存放。除了保存Class文件中描述的符号引用外,还会把翻译出来的直接引用也存储在运行时常量池中。
并非预置入Class文件中常量池的内容才能进入方法区的运行时常量池,运行期间也可能将新的常量放入池中,例如String类的intern()方法。
我们知道,方法区是放在内存中的,而运行时常量池是在方法区中的,那么就可能出现申请不到内存的情况,所以,它也有OutOfMemoryError。
2、直接内存
下面,介绍一下上面提到的字面量等词。
1、java字面量:
int i = 1;把整数1赋值给int型变量i,整数1就是Java字面量,
同样,String s = "abc";中的abc也是字面量。
2、符号引用
符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能够无歧义的定位到目标即可。例如,在Class文件中它以CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info等类型的常量出现。符号引用与虚拟机的内存布局无关,引用的目标并不一定加载到内存中。在Java中,一个java类将会编译成一个class文件。在编译时,java类并不知道所引用的类的实际地址,因此只能使用符号引用来代替。比如org.simple.People类引用了org.simple.Language类,在编译时People类并不知道Language类的实际内存地址,因此只能使用符号org.simple.Language(假设是这个,当然实际中是由类似于CONSTANT_Class_info的常量来表示的)来表示Language类的地址。各种虚拟机实现的内存布局可能有所不同,但是它们能接受的符号引用都是一致的,因为符号引用的字面量形式明确定义在Java虚拟机规范的Class文件格式中。
3、直接引用
本文参考了以下文章:
http://blog.csdn.net/u010850285/article/details/44152157
http://blog.csdn.net/u014656992/article/details/51107127