Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java在内存中是什么样子的_Java_Memory - Fatal编程技术网

Java在内存中是什么样子的

Java在内存中是什么样子的,java,memory,Java,Memory,我是java新手,还在学习。我脑子里想的是内部和匿名类。现在我有一个关于java在内存中是什么样子的技术问题,当分配对象、定义类等时 比如,当我有一个字段是在外部类和内部类中定义的对象时,内存是什么样子的。静态类与非静态类看起来不同吗 我只需要一个视觉参考 谢谢大家详细信息在实现中(而不是规范中)。然而,实现通常遵循一个非常简单的模式。Java中的大部分内存布局都非常简单明了。我的术语可能与Java术语不匹配,因为我没有做很多Java编程 通常,对象以指向其vtable的指针开始,然后有一组字段

我是java新手,还在学习。我脑子里想的是内部和匿名类。现在我有一个关于java在内存中是什么样子的技术问题,当分配对象、定义类等时

比如,当我有一个字段是在外部类和内部类中定义的对象时,内存是什么样子的。静态类与非静态类看起来不同吗

我只需要一个视觉参考


谢谢大家

详细信息在实现中(而不是规范中)。然而,实现通常遵循一个非常简单的模式。Java中的大部分内存布局都非常简单明了。我的术语可能与Java术语不匹配,因为我没有做很多Java编程

通常,对象以指向其vtable的指针开始,然后有一组字段跟随。字段是基本类型(int/bool/float)或指向对象的指针。对象就是这样。(类也是对象。)空指针类似于C,它们是无效的,不像Python,在Python中没有对象

在内部类中,有一个额外的隐藏字段指向外部类的实例。这是内部类访问外部类中数据的方式。匿名类也是这样工作的。静态方法只是类上的方法,而不是实例上的方法

vtable是所有魔法发生的地方。每个类都有自己的vtable,在所有对象之间共享。vtable包含有关该类的信息,例如其实例的大小以及字段的布局方式。此信息由垃圾收集器使用。vtable还有一个指向该类实现的所有方法的指针。调用方法时,运行时首先从对象中获取vtable指针,然后从vtable中获取方法指针,然后调用该方法并将该对象作为隐式参数传递给该方法。它类似于C++,但实现起来要简单得多。如果方法或类为“final”,则可以跳过该过程

我知道Java实际上没有“指针”,它有“符号句柄”之类的东西,但常见的实现只是使用普通的旧指针

比如当我 具有一个字段,该字段是 在外部类与 内部阶级。静态类看起来怎么样 与非静态不同

非静态内部(或匿名)类的实例将引用用于实例化它的外部类实例。这就是允许内部类中的方法引用封闭类中声明的实例级成员的原因。通常,该引用作为构造函数中隐藏的额外参数传递给内部类。但如果使用反射创建内部类实例,则必须显式提供该额外参数

(请注意,当匿名类在实例化它的方法范围内使用局部变量/参数时,会使用不同的机制…)

如果需要更多细节,可以使用javap来分解一些简单示例类的字节码

我只需要一个视觉参考


对不起,我不喜欢漂亮的图片:-)

欢迎来到Java世界。与C语言不同,C语言的语言结构和内存表示几乎是一对一的映射,Java稍微复杂一些

首先,当人们谈到Java时,它可能意味着两件事:Java语言和Java平台。在这里,我的意思是Java是编程语言Java。用Java编写的代码首先被编译成字节码,即Java虚拟机的机器代码。如果您对Java语言的细节感兴趣,下面是。对于JVM,有两个

当我有一个字段是在外部类和内部类中定义的对象时,内存是什么样子的

我将解释为Java虚拟机中的内存布局是什么样子,因为物理布局取决于JVM的实现。为此我略读了一下

与Java语言一样,Java虚拟机操作两种类型:基本类型和引用类型。相应地,有两种值可以存储在变量中,作为参数传递,由方法返回,并对其进行操作:原语值和引用值

Java虚拟机希望几乎所有类型检查都在编译时完成,而不是由Java虚拟机本身完成。特别是,数据无需标记或可检查以确定类型

对对象的引用被认为具有Java虚拟机类型
reference
reference
类型的值可以看作是指向对象的指针

所以答案似乎是,这两个字段看起来完全一样:
reference

有用的链接

静态(嵌套)类的工作方式与顶级类完全相同。唯一的区别是它的名称前面有另一个类名。(如果查看编译后的.class文件,您会发现在名为Outer的类中嵌套名为Nested的类会得到类似于“Outer$Nested.class”的内容。)

内部类有一个隐藏字段,该字段是对其外部类的包含实例的引用。当你写作时:

class Outer {
  final int x;

  class Nested {
    int y;

    Nested(int y) {
      this.y = y;
    }

    int bar() {
      return x + y;
    }
  }

  void foo() {
    Nested n = new Nested(5);
  }
}
就好像你写过:

class Outer {
  final int x;

  static class Nested {
    Outer outer;
    int y;

    Nested(Outer outer, int y) {
      this.outer = outer;
      this.y = y;
    }

    int bar() {
      return outer.x + y;
    }
  }

  void foo() {
    Nested n = new Nested(this, 5);
  }
}
隐藏字段的名称(我在这里称为“外部”)是隐藏的 对你来说,虽然你可以通过说
Outer来引用它。这是
内部类(其中
Outer
当然是外部类的名称)。 同样,请注意,当内部类中的方法引用 在外部类中,引用实际上是通过隐藏的 对外部类的引用

关于访问控制(例如:私有)如何与n一起工作,还有一些额外的复杂性
public class I {
    class inner {
        public void ctor() {};
    }
}
class I$inner {

  // Field descriptor #6 LI;
  final synthetic I this$0;

  // Method descriptor #8 (LI;)V
  // Stack: 2, Locals: 2
  I$inner(I arg0);
     0  aload_0 [this]
     1  aload_1
     2  putfield I$inner.this$0 : I [10]
     5  aload_0 [this]
     6  invokespecial java.lang.Object() [12]
     9  return
      Line numbers:
        [pc: 0, line: 3]
      Local variable table:
        [pc: 0, pc: 10] local: this index: 0 type: I.inner

  // Method descriptor #14 ()V
  // Stack: 0, Locals: 1
  public void ctor();
    0  return
      Line numbers:
        [pc: 0, line: 4]
      Local variable table:
        [pc: 0, pc: 1] local: this index: 0 type: I.inner
}