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

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

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

JVM是否会在对象创建时为10个实例分配10个不同的内存空间(我的意思是在我调用构造函数时,即新的MyClass();

它可能会做,但是通过逃逸分析,它可以将它们放在堆栈上或完全消除它们。

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

如果您有一个ClassLoader,您将获得该类的一个实例,但是如果每个实例都有自己的ClassLoader,您将在每个ClassLoader中获得该类的副本。 注意:每个ClassLoader可以具有相同名称的不同版本的类。

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

它在PermGen(Java <7)或MetaSpace(Java 8+)中存储在堆中的类和方法信息(包括字节代码)

实际的实例在名义上被添加到堆中,但不一定是。

我不确定尚未调用的方法是否在每个对象的内存中分配不同?

JVM经历了许多优化阶段,当您调用方法时,它可能会优化它,内联它甚至消除它。 您可以通过在命令行上添加-XX:+PrintCompilation来查看正在编译(甚至重新优化)的方法。

是。 类元数据被加载到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