JVM保存有关引用和对象类型的信息

时间:2016-05-24 14:08:02

标签: java jvm java-memory-model

我正在努力加深我对Java内存模型和JVM的了解。

基本概念很简单,但我无法理解JVM在哪里保存有关基元,对象和引用的类型的信息。

例如 1.我们有变量int i = 0。 该值存储在线程的堆栈中。这只是一个4字节,在RAM或/和CPU缓存中包含值0x0000。但它不包含任何有关其类型的信息。 想象一下,您可以直接访问内存中的这些字节。你不能确定它是一个整数。据我所知,你不能对它的类型说什么。这只是4个字节的信息。

因此,JVM必须在其他地方保留关于其类型的一些信息,但JVM在何处以及如何保留它?

  1. 参考对象 A级{} B类延伸A {}
  2. obj = new B();

    在这种情况下,我们有这样的事情:

    |堆栈| | HEAP | | PermGen的|

    “参考”----> “对象”“A”,“B”。

    引用位于堆栈中,类型为“A”,但引用仅包含存储“对象”的信息。它有8字节(如果JVM使用少于32GB,可以压缩到4byte)。它没有关于这8个字节的类型的任何信息。

    “Object”位于堆中,类型为“B”。我不知道它是否有任何关于其类型的信息...

    1. 引用泛型。 List list = new ArrayList<>(); JVM在何处以及如何保存有关对象和引用的每种类型的信息?
    2. 我希望有人能说清楚。

1 个答案:

答案 0 :(得分:5)

  

我无法理解JVM在哪里保存有关基元,对象和引用的类型的信息。

JVM有一个空间(Perm Gen或Metaspace),用于记录所有类型信息和代码。

  

这只是4个字节的信息。

是的,它可能是一个布尔值,一个int或一个32位的引用。很可能它在寄存器中,这意味着它甚至不使用任何内存。

  

JVM必须在其他地方保留有关其类型的一些信息,但是JVM在何处以及如何保留它?

实际上它并没有。如果能够在每次访问时查找此类信息,那将非常缓慢。相反,它有机器代码,它将4字节值放入寄存器,然后假设它是它所期望的类型。

它需要跟踪的唯一事情是哪些寄存器保存引用,哪些寄存器保存原语。它需要这个来执行GC。

正在运行的代码可以包含有关哪些寄存器和哪些堆栈位置具有引用的元信息。除非重新编译代码,否则不会动态分配寄存器。

  

引用泛型。 List list = new ArrayList<>(); JVM在何处以及如何保存有关对象和引用的每种类型的信息?

它没有。泛型是一个编译时功能。

您可以在运行时获取一些信息,但这不适用于对象,仅适用于类。