【问题标题】:Java static method memory allocationJava静态方法内存分配
【发布时间】:2023-03-10 12:43:01
【问题描述】:

我对Java静态方法内存分配有疑问。我有三个类,

class a {
public static void a() {}
}
class b {
public static void a() {}
}
class c {
public static void a() {}
}

这里所有三个类都有一个具有相同签名的静态方法 a()。 我的疑问是,这里将如何创建内存?我的意思是在堆或三个内存空间中为方法 a() 只创建一个内存?

考虑以上三个类是挂毯页面。如果用户进入A类,静态方法内存将被创建/分配,然后我重定向到B类,这里我也有相同的静态方法。 我的疑问是,这里是否会为 B 类静态方法创建内存。

【问题讨论】:

    标签: java memory memory-management static


    【解决方案1】:

    如果这是您的问题,编译器不会“重复”方法。运行时也没有(如果有的话,内联方法调用的性能优化正好相反)。

    如果您有通用代码,则由您来重构可重用的部分,然后重用它们。

    【讨论】:

      【解决方案2】:

      这里所有三个类都有一个具有相同签名的静态方法 a()。我的疑问是,这里将如何创建内存?

      如果您调用这些方法,它们可以加载到 Perm Gen 或 Metaspace。

      我的意思是只会在堆中为方法a()创建一个内存还是三个内存空间?

      堆上没有使用空间。如果你使用所有三个方法,每个方法都会被加载到内存中。

      这里会为B类静态方法创建或不创建内存。

      将使用更多内存,但只有几个字节,而且只有一次。除非你的方法很大,否则这不会有太大的不同。

      【讨论】:

      • 吹毛求疵:方法不是在类加载时加载(即使它从未被调用)?方法定义和字节码不是也放入堆内存中(与类的其余部分相同)吗?还是有(仍然?)它的特殊区域? (当然,从那里热点的任何本机代码都可能转到其他地方)
      • @Thilo 可以立即加载类的字节码,尽管该方法可能仅在您第一次调用时才从字节码中提取(这可能取决于实现)。定义和字节码没有缓存在堆上,没有办法得到一个类的原始字节码(你可以得到一个你认为是相同的副本,但它是另一个副本)
      • @Thilo 您可以尝试通过查看类路径来获取类的字节码,但是您可以使用 defineClass 或 Instrumentation 为类加载不同的字节码,并且无法查看结果byteCode 是(除非您是最后一个 Instrumentation 代理,并且您保留一份副本以供以后使用)像 lambdas 和反射处理程序这样的类是动态生成的,您无法从堆中检索它们并且不会出现在堆转储中。
      • 但是当我们有太多类时,不是有所谓的“permGen”(堆的一部分)吗?
      • @Thilo PermGen 已死,Metaspace 仍然存在(不是 PermGen 2.0 ;),如果您为它设置最大大小,它会做同样的事情。
      猜你喜欢
      • 2011-12-02
      • 1970-01-01
      • 2016-01-26
      • 1970-01-01
      • 2012-01-13
      • 2016-02-01
      • 1970-01-01
      • 2014-10-12
      • 2015-07-23
      相关资源
      最近更新 更多