在Java中加载类时如何管理内存?

在Java中加载类时如何管理内存?,java,jvm,Java,Jvm,假设我有一个包含10个方法的类,我需要从该类实例化10个对象。 问题是:JVM会在对象创建时为10个实例分配10个不同的内存空间吗(我的意思是在调用构造函数时,即new MyClass();?或者它会在内存中加载一次类定义,每个实例在调用这10个方法时,JVM会在运行时分配内存吗 为了澄清一些误解,我的问题是在创建对象时,我知道所有数据成员都分配在堆内存中,但我不确定尚未调用的方法是否在内存中为每个对象分配了不同的方法?是。类元数据加载到Permgen空间(Java8中的MetaSpace)因此

假设我有一个包含10个方法的类,我需要从该类实例化10个对象。 问题是:JVM会在对象创建时为10个实例分配10个不同的内存空间吗(我的意思是在调用构造函数时,即new MyClass();?或者它会在内存中加载一次类定义,每个实例在调用这10个方法时,JVM会在运行时分配内存吗


为了澄清一些误解,我的问题是在创建对象时,我知道所有数据成员都分配在堆内存中,但我不确定尚未调用的方法是否在内存中为每个对象分配了不同的方法?

是。类元数据加载到Permgen空间(Java8中的MetaSpace)因此,加载类后,所有方法都可用(静态和非静态)。未调用的方法也将作为此元数据的一部分加载。所有方法仅加载一次。

加载类时,类的所有方法(静态和非静态)也加载到内存中。无论有多少都在加载

JVM将为每个对象分配不同的内存位置

假设

MyClass m1 = new MyClass(); // one memory location

MyClass m2 = new MyClass(); // different location

MyClass m3 = m1; // same memory location of m1 object
JVM是否会在对象创建时为10个实例分配10个不同的内存空间(我的意思是在调用构造函数时,即new MyClass()

不过,通过转义分析,它可以将它们放在堆栈上或完全消除它们

或者,它将在内存中加载一次类定义,并在调用这10个方法中的每一个时加载每个实例,在运行时,JVM将分配内存

如果你有一个类加载器,你会得到一个类实例,但是如果每个实例都有自己的类加载器,你会在每个类加载器中得到一个类的副本。注意:每个类加载器可能有一个同名的不同版本的类

为了澄清一些误解,我的问题是在创建对象时,我知道所有数据成员都分配在堆内存中


它存储在PermGen堆外的类和方法信息(包括字节码)(Java方法不需要为每个实例单独分配;它们只需要与类一起加载。我们是否可以证明发生了堆栈分配而不是堆分配?@不过,您可以看到没有产生垃圾。一个简单的例子是使用lambdas,这很容易消除。如果您运行一些简单的代码,则通过一个小堆,您将看到GCs,直到代码被优化为止
-XX:+PrintCompliation
(打印方法已编译)和
-XX:BCEATraceLevel=3
(已执行转义分析的打印)在此之后,如果所有对象都放在堆栈上,您可以看到没有地面军事系统。您还可以使用飞行记录器查看对象创建的时间。