当前位置: 代码迷 >> java >> 当JVM执行新的关键字创建对象时会发生什么?
  详细解决方案

当JVM执行新的关键字创建对象时会发生什么?

热度:34   发布时间:2023-08-02 10:41:01.0

我知道JVM使用堆栈和堆为对象引用分配内存,为方法分配对象值和内存。 但是我对术语感到困惑:METHOD AREA,HEAP和JAVA STACK,我没有几个问题。

  1. 当我们说“ ClassName obj = new ClassName()”时,new在HEAP上创建了一个对象(实例变量和静态变量也是如此),返回给reference(obj)的对象是什么? 有人习惯说它是CLASS TYPE,是否表示哈希码?

  2. 当new在堆上创建对象时,同时:i)对应于该对象的方法ii)局部变量和iii)对该对象的引用存储为STACK的一部分(是否是JAVA STACK?)。 如果是这样,那么METHOD AREA做什么? 还是我错了?

  3. 为该对象分配的内存量是多少?
    一世。 供对象参考
    ii。 用于对象值(取决于局部变量)
    iii。 (因为非静态成员不在对象之间共享,并且为每个对象(包括方法)维护一个单独的副本),会分配内存来指向对象的方法吗?

顺便说一句,静态方法存储在哪里?

当我们说“ ClassName obj = new ClassName()”时,new在HEAP上创建了一个对象(实例变量和静态变量也是如此),返回给reference(obj)的对象是什么? 有人习惯说它是CLASS TYPE,是否表示哈希码?

是的,新的会在HEAP上创建对象。 堆是存储对象及其实例变量的内存位置。 不是静态变量,因为静态变量不属于对象,它属于类,因此存储在PermGem节中(与类有关的数据,与实例无关)。

返回值:引用(指针/内存地址),即哈希码

当new在堆上创建对象时,同时:i)对应于该对象的方法ii)局部变量和iii)对该对象的引用存储为STACK的一部分(是否是JAVA STACK?)。 如果是这样,那么METHOD AREA做什么? 还是我错了?

因为所有线程共享相同的方法区域,所以方法并不对应于它属于类的对象

方法区域的作用:方法区域存储每个类的信息,例如运行时常量池,方法代码,方法的返回类型(或void)等

为该对象分配的内存量是多少? 一世。 供对象参考ii。 用于对象值(取决于局部变量)iii。 (因为非静态成员不在对象之间共享,并且为每个对象(包括方法)维护一个单独的副本),会分配内存来指向对象的方法吗?

对象引用的内存量:它取决于许多VM,引用的大小是本机指针的大小 ,对于(iii)以上点,已经清除了该内容:

我知道JVM使用堆栈和堆为对象分配内存

正确。

对象值

我假设您是指对象的标题和字段。

和方法的记忆。

方法未存储在堆或堆栈中。 当您探查堆使用情况或设置最大堆大小时,方法的使用没有什么区别,因为它们不在Oracle或OpenJDK JVM中的堆上。

它们存储在PermGen或MetaSpace或其他一些空间中,具体取决于您使用的JVM。

但是我对以下术语感到困惑:METHOD AREA,

从Java中的

Java虚拟机具有一个在所有Java虚拟机线程之间共享的方法区域。 该方法区域类似于常规语言的编译代码的存储区域,或者类似于操作系统过程中的“文本”段。 它存储每个类的结构,例如运行时常量池,字段和方法数据,以及方法和构造函数的代码,包括用于类和实例初始化以及接口初始化的特殊方法(§2.9)。

共享空间用于存储对象。 这通常是由JVM管理的本地内存的一个连续区域。

和JAVA STACK

线程的堆栈实际上是大多数JVM上的本机线程堆栈。

当我们说“ ClassName obj = new ClassName()”时,new在HEAP上创建一个对象(实例变量和静态变量也是如此)

可以,但也可以通过转义分析消除对象,将字段放在堆栈上,甚至可以消除这些对象。

并将什么返回给reference(obj)?

正确,Java仅具有引用和原语(如果您忽略都不是的void类型)

有人说这是CLASS TYPE,

通过给出引用的类型(类或接口)来定义引用。

这意味着哈希码吗?

哈希码是对象的哈希值。 它与您提到的其他内容无关。

当new在堆上创建对象时,

在堆上创建new对象时,只需为对象的标题(指向类及其方法)和其字段的空间创建空间。 (那些JVM没有优化掉)

同时:i)方法

该方法在各个阶段进行加载/编译。 这些方法是在第一次需要时加载的,以后再进行编译(如果需要的话)。

对应于该对象ii)局部变量

局部变量在堆栈上,不在堆上,不在对象中。

iii)对该对象的引用存储为STACK的一部分(是否是JAVA STACK?)。

Java堆栈是堆栈,是本机堆栈。

如果是这样,那么METHOD AREA做什么?

存储方法的代码。

为该对象分配的内存量是多少?

每个标头大约8-12个字节,每个原始字段的空间以及8或16个字节(32 GB-64 GB堆)的引用和对齐填充。

一世。 供对象参考

通常,在64位JVM(使用压缩的oop)上,它是32位的。 如果您有超过64 GB的堆,它将是64位。

ii。 用于对象值(取决于局部变量)

局部变量在堆上而不是对象上。

iii。 是否会分配一个内存来指向对象的方法?

方法内存使用对您不可见。 它既不在堆上,也不在每种方法的基础上进行度量。 我不知道一个探查器甚至可以向您显示。

(因为非静态成员不在对象之间共享,并且为每个对象(包括方法)维护一个单独的副本)。

这听起来像是对空间的疯狂浪费,这就是JVM这样做的原因。 一个方法只有一个副本,与实例数无关。

顺便说一句,静态方法存储在哪里?

与所有其他方法。 静态方法和非静态方法之间没有区别,只是非静态方法必须将实例作为其在JVM级别的第一个参数。 (并且修饰符中有一点可以说它是否是静态的)

  相关解决方案