jvm 在运行时从静态方法构建的许多示例的内存占用是多少?

chhkpiq4  于 2022-11-23  发布在  其他
关注(0)|答案(1)|浏览(115)

我读过一些讨论静态类变量加载和静态方法加载的文章,但很少有关于从静态方法返回的示例化对象及其足迹的文章。
从静态方法返回示例实际上是创建单例的方式,但是单例应该创建一次,然后由某个getInstance方法访问。
如果我自愿地想要打破单例模式,那么如果我编写类似下面的代码会发生什么?(注意RandomSumBuilder build()方法的静态访问修饰符)

public class Service {

    public void doSomething() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("Random sum : " + RandomSumBuilder.add().build());
        }
    }
}

public class RandomSumBuilder {
    private List<Integer> aList = new ArrayList<>();

    public RandomSumBuilder() { }

    public static RandomSumBuilder add() {
        RandomSumBuilder randomSumBuilder = new RandomSumBuilder();
        randomSumBuilder.aList.add(new Random().nextInt(11));
        return randomSumBuilder;
    }

    public int build() {
        return aList.stream()
                .reduce(Integer::sum)
                .orElse(0);

    }
}

对我来说,很明显,RandomSumBuilder不能被认为是单例的,但是我不能让我的头围绕这些问题,我只能做出假设。
1.不同的RandomSumBuilder示例是静态的吗?

  • 我会说是的,就像单身狗一样 *

1.是否可以选择这些对象进行垃圾回收?

  • (根据我对问题1的回答,我会说不)*

1.它是否在类加载器上增加了不必要的工作?

  • (如果必须加载那么多RandomSumBuilder来示例化这些静态对象,我会说是的,因为我不认为保持它们全局性有什么意义。我用visualvm进行的快速本地测试无法帮助我做出决定)*

1.构建器模式(带有嵌套类)会带来什么呢?

  • (我想说创建的静态对象和类加载工作少得多,但在我的第四个连续假设,我甚至不确定)*

我希望我在这个问题上没有太迷失,如果我错了请纠正我。

50pmv0ei

50pmv0ei1#

请注意,您的示例是不可编译的,因此无法确定
1.不同的RandomSumBuilder示例是静态的吗?
这个问题毫无意义。
说真的,没有静态示例这回事。
例如:

public class Test {
    public static Test myTest = new Test();
 }

myTest * 变量 * 是静态变量,但它所指向的 * 示例 * 与Test的任何其他示例没有区别。
它不是一个“静态示例”。* 没有这样的东西。*
第二个问题是,您的示例根本没有创建任何RandomSumBuilder示例。
1.是否可以选择1这些对象进行垃圾回收?
是的。假设它们没有被 * 分配 * 给某个使其可达的东西。
1.它是否在类加载器上增加了不必要的工作?
不会。除非你创建多个类加载器,否则类只加载一次。类加载器不会参与创建示例。
1.构建器模式(带有嵌套类)会带来什么呢?
一个对象是如何被创建的,它的可达性是没有区别的,创建它的方法是静态的,内部的还是嵌套的也没有区别。
另一方面,您的程式码会执行下列动作:

instanceB.aList.add(new Random().nextInt(11));

因为instanceB没有声明,所以不能编译,但是如果instanceB声明,并且它是static,那么这就足以使你(可能)创建的Integer可达。
但这与build方法是静态的无关...
1 -英语错误:你把“候选人”等同于“选举”。垃圾收集是不民主的。而且即使在真实的世界中,候选人也有比这更广泛的含义。查字典...

相关问题