垃圾收集程序怎样判断栈上的值是否为对象引用

「如果每个slot都带个类型的标识会比较浪费。」是的,实际上就是这么做的:Chapter 4. The class File Formatjavac编译时会在class文件中生成stackmap,包含各方法运行到特定节点时的栈信息。没记错的话,JVM在加载class文件时还会再校验一遍stackmap,以防恶意构造class文件进行攻击。因为这个过程比较耗时,当年J2ME/CLDC里面做了一个preverifier,把一部分校验工作放在编译打包时做了。
■网友
Java没有栈上对象,栈上变量存储的不是基本数据类型就是指向堆上对象的指针。垃圾回收不用管栈上变量,进入方法开辟栈上空间,退出方法回收栈上空间即可。~~~~~~以下为猜测:JVM应该有办法准确判断当前时点局部变量类型才行,要不然就是可以从方法的字节码中推算出,要不然就是有专门记录的表。肯定无法通过数据本身来猜测数据类型。
■网友
关于本地变量表中类型的识别:
javac编译之后得到了字节码,虚拟机运行的时候可以根据操作码知道对应操作数的数据类型,数据长度,例如:
ALOAD: aload_0,astore_0,a开头的这些操作码就是表示要操作的数据类型为 对象或者数组。类似的还有aaload,aastore
0x19 aload 将指定的引用类型本地变量0x3a astore 将栈顶引用型数值存入指定本地变量0x53 aastore 将栈顶引用型数值存入指定数组的指定索引位置0x32 aaload 将引用型数组指定索引的值推送至栈顶而对象类型,以及数组类型,说明这个变量就是引用类型。
一开始我审题不仔细,现在发现这样回答还不太合理。
关于垃圾回收的过程中对对象的查找
记得在书上看到的垃圾回收程序,是直接在堆上操作的,题主说的局部变量表,是在栈上面的,准确说是在栈帧上面,如果垃圾回收程序需要根据栈帧判断,那是不可能的,因为随时都在发生栈帧的入栈和销毁。
垃圾回收算法中,有对象引用树根的,其中引用计数法的垃圾回收算法,就是类似于链表结构,记录了存活的对象,通过指针进行引用。虽然引用计数法不能处理循环引用,现有的其他垃圾回收算法应该也是类似,需要用对象引用的树根(gc root)开始索引查找,应该是配合了引用计数的方法。
而在gc程序在直接扫描堆的过程中,肯定是只对栈里的引用类型的数据,也就是对象或者数组进行垃圾回收处理。
垃圾收集程序怎样判断栈上的值是否为对象引用
【垃圾收集程序怎样判断栈上的值是否为对象引用】
参考链接:How Garbage Collection Works - Java Enterprise Performance


    推荐阅读