会导致栈溢出
StackOverflowError它是一种错误,不是异常:(OutOfMemoryError也是错误)
OutOfMemoryError和StackOverflowError都属于VirtualMachineError的一种
下面讲一下方法区、栈、堆三者的关系:
1.HotSpot是sun公司创建的JVM;(我们学习及使用的JVM,一般都是指sun公司创建的这个HotSpot)(所以引用通过指针,指向访问对象,没什么好解释的了)
其它公司也可以自己创建一种jvm,取其它的名字。(如Oracle的JRockit、IBM的J9也都是非常有名的JVM)
如图所示:
2.元数据:数据的数据;
3.类元数据(存放在方法区中,但是在堆中存有访问它们的指针(具体在堆中每个对象的对象头中的Class Point)):描述对象数据的类数据(即描述这个对象属于哪个类,这个类的一些信息),通过堆中存放的类元数据的地址,可以判断出堆中存放的对象哪些是同一类对象,哪些不是同一类对象呢:根据这些对象的描述数据(通过指针,访问指定地址的方式)(即元数据,存放在方法区中),来看它们是否是属于同一类(即同一模板,即同一Class!!!!)(即堆中存放对象,这些对象还保有一个指针,指向方法区中它们自己所对应的类的描述数据,也称为类的元数据),上面这段话结合下图一起看效果好:
上面这种不使用句柄池的方式称为“直接访问”
然而实际上除了使用指针直接访问reference指向的堆中对象,还可以使用句柄池:Java 堆中会分配一块内存作为句柄池。reference 存储的是句柄地址。
使用句柄的最大好处是 reference 中存储的是稳定的句柄地址,在对象移动(GC)是只改变句柄池中实例数据指针地址,reference 自身不需要修改。
直接指针访问的最大好处是速度快,节省了一次指针定位的时间开销。