堆
Java程序在运行时创建的所有类实例或数组都放在同一个堆中。而一个Java虚拟机实例中只有一个堆空间,因此所有线程都将共享这个堆。由于一个Java程序独占一个Java虚拟机实例,因而每个Java程序都有自己的堆空间。
Java虚拟机有一条在堆中分配新对象的指令,却没有释放内存的指令,正如你无法用Java代码去明确释放一个对象一样,字节码指令也没有对应的功能。虚拟机自己负责决定如何已经合适释放不在被运行的程序引用的对象所占据的内存。程序本身不用去考虑何时需要回收对象所占用的内存,通常,虚拟机把这个任务交给垃圾收集器。(北大青鸟北京通州校区,软件技术培训)
垃圾回收
垃圾收集器的主要工作是自动回收不在被运行的程序所引用的对象所占用的内存。此外,它也可能去移动那些还在使用的对象,以此减少堆碎片。
对象内部表示
Java对象中包含的基本数据由它所属的类及其所有超类声明的实例变量组成。只有有一个对象引用,虚拟机就必须能够快速定位对象实例的数据。另外,它必须能通过该对象引用访问相应的类数据(存储于方法区的类型信息),在对象中通常有一个指向方法区的指针。
对象引用可认为是一个本地指针。通过某种策略可由该指针找到实例数据以及class data。
有如下几个理由要求虚拟机必须能够通过对象引用得到类数据(class data):
1. 当程序在运行时需要转换某个对象引用为另一种类型,虚拟机必须能检查这种转换是否被允许。被转换的对象是否的确是被引用的对象或它的超类。
2. 当程序执行 instanceof操作时,虚拟机也进行了同样的检查。(北大青鸟北京通州校区,软件技术培训)
3. 在程序中调用某个实例方法时,虚拟机必须进行动态绑定。不能按照引用的类型(type of reference),而是按照对象的实际类。
因此,虚拟机必须再次通过对象的引用去访问类数据。
北大青鸟北京通州校区