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

时间:2015-07-19 13:21:16

标签: java jvm new-operator

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

  1. 当我们说" ClassName obj = new ClassName()"时,new会在HEAP上创建一个对象(实例变量和静态变量)以及返回给引用的内容(obj) )?有人说它是CLASS TYPE,它是否代表哈希码?

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

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

  4. 顺便说一下,静态方法存储在哪里?

2 个答案:

答案 0 :(得分:0)

  

当我们说" ClassName obj = new ClassName()"时,new会创建一个对象   关于HEAP(实例变量和静态变量)以及什么   返回参考(obj)?有人说它是CLASS   TYPE,是指哈希码?

是新创建HEAP上的Object。堆是存储对象及其实例变量的存储位置。不是静态变量,因为静态变量不属于它属于类的Object,因此存储在PermGem Sections(类相关数据,而不是实例相关)上。

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

  

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

由于所有线程共享相同的方法区域方法,因此不对应于它属于类

的对象

METHOD AREA做了什么:方法区域存储每类信息,如运行时常量池,方法代码,方法的返回类型(或无效)等

  

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

对象引用的内存量:它依赖于许多VM,引用的大小是本机指针大小,并且(iii)上面的点已经清除

答案 1 :(得分:0)

  

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

正确。

  

对象值

我假设你的意思是对象的标题和字段。

  

和方法的记忆。

方法不存储在堆或堆栈中。在分析堆使用情况或设置最大堆大小时,方法的使用没有区别,因为它们不在Oracle或OpenJDK JVM的堆中。

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

  

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

来自Java中的Method Area

  

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

     

HEAP

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

  

和JAVA STACK

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

  

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

它可能,但它也可以通过转义分析消除对象,将字段放在堆栈上,并可能消除它们。

  

什么返回参考(obj)?

正确,Java只有引用和原语(如果你忽略了void类型,那么

  

有些人会说它是CLASS TYPE,

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

  

是指哈希码?

哈希码是对象的哈希值。它与你提到的任何其他内容都没有关系。

  

当new在堆上创建对象时,

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

  

同时:i)方法

在各个阶段加载/编译方法。这些方法是第一次需要加载的,如果它们被编译就会加载。

  

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

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

  

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

Java Stack是Stack,是本机堆栈。

  

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

存储方法的代码。

  

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

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

  

我。用于对象引用

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

  

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

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

  

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

您无法看到方法内存使用情况。它不在堆上,也不能在每个方法的基础上测量。我不知道哪个分析器甚至可以告诉你这个。

  

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

这听起来像是浪费空间,这就是JVM确实这样做的原因。无论实例数是多少,方法只有一个副本。

  

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

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