Java 什么需要更多内存-嵌套类/单独类

Java 什么需要更多内存-嵌套类/单独类,java,class,nested-class,Java,Class,Nested Class,什么会占用更多内存: 创建嵌套类 创建单独的类 这不是一个与OO/设计相关的问题,我只是想知道答案 先谢谢你 举例说明: 情景一 java public class Car { ArrayList< Door > = new ArrayList< Door >() // Methods doing operations on Door } ==================================或===========================

什么会占用更多内存:

  • 创建嵌套类
  • 创建单独的类
  • 这不是一个与OO/设计相关的问题,我只是想知道答案

    先谢谢你

    举例说明:

    情景一

    java

    public class Car {
    
    ArrayList< Door > = new ArrayList< Door >()
    
    // Methods doing operations on Door
    
    }
    
    ==================================或===========================

    情景2

    Cars.java

    public class Car {
    
    
    ArrayList< Door > = new ArrayList< Door > ()
    
    // Methods doing operations on Door
    
    public class Door {
    
    }
    
    }
    
    公车{
    ArrayList=新的ArrayList()
    //方法在门上做手术
    公共舱门{
    }
    }
    
    如果
    Door
    上的所有操作都是由class
    Car
    完成的,那么上述哪种情况的内存效率更高。没有其他类访问

    • 据我所知,原始值总是位于堆栈上。 引用对象被创建并存在于堆中,而每个对象的 引用变量与堆栈的其余部分一样存在于堆栈中 原语
    • 执行方法就是执行方法,规则将 始终适用于事物的生存和消亡(即堆或堆栈)。 所以,为了纠正你的措辞。。。你应该说“记忆怎么样?” 对于分配的变量和某些方法的位置…”
    • 内部类只是内部化的常规类 所有其他很酷的类,它们只是 您最终将(在堆上)创建,只有这样,您才能 由于您的内部类而使用内存
    • 然而,从技术上讲,实际上存在一个浮动的“类对象” 在你的内部类的某个地方,如果你有静态成员 在这些变量中,它会占用一些内存
    • 将封闭类及其内部类视为单向类 协会。孩子需要知道父母是谁,但是 父母不在乎(意译)
    • 如果您确实需要获取内部类实例的数据,您可以 可以将其存储在封闭空间中的常规ol'实例变量中 像通常一样初始化并调用它上的方法

    如果不抱歉浪费您的时间的话,我想这会有点帮助。

    我所做的这个测试很快就估计出单独、嵌套和静态嵌套类的大小大致相同:

    // separate class
    class Separate { byte[] x = new byte[1000]; }
    
    public class Test1 {
    
        // non-static nested
        class Nested { byte[] x = new byte[1000]; }
    
        // static nested
        static class StaticNested { byte[] x = new byte[1000]; }
    
        static long getFreeMemory () {
            // waits for free memory measurement to stabilize
            long init = Runtime.getRuntime().freeMemory(), init2;
            int count = 0;
            do {
                System.out.println("waiting..." + init);
                System.gc();
                try { Thread.sleep(250); } catch (Exception x) { }
                init2 = init;
                init = Runtime.getRuntime().freeMemory();
                if (init == init2) ++ count; else count = 0;
            } while (count < 5);
            System.out.println("ok..." + init);
            return init;
        }
    
        Test1 () {
    
            Object[] s = new Object[10000];
            Object[] n = new Object[10000];
            Object[] t = new Object[10000];
    
            long init = getFreeMemory();
    
            for (int j = 0; j < 10000; ++ j)
                s[j] = new Separate();
    
            long afters = getFreeMemory();
    
            for (int j = 0; j < 10000; ++ j)
                n[j] = new Nested();
    
            long aftersn = getFreeMemory();
    
            for (int j = 0; j < 10000; ++ j)
                t[j] = new StaticNested();
    
            long aftersnt = getFreeMemory();
    
            System.out.println("separate:      " + -(afters - init) + " each=" + -(afters - init) / 10000);
            System.out.println("nested:        " + -(aftersn - afters) + " each=" + -(aftersn - afters) / 10000);
            System.out.println("static nested: " + -(aftersnt - aftersn) + " each=" + -(aftersnt - aftersn) / 10000);
    
        }
    
        public static void main (String[] args) {
            new Test1();
        }
    
    }
    
    如果没有成员字段(也没有分配的字节数组),则输出为:

    separate:      160000 each=16
    nested:        160000 each=16
    static nested: 160000 each=16
    
    这与我们的预期相符(参见示例)

    它通过在每一轮实例化之后测量空闲内存中的差异来工作
    freemory()
    等待GC在后台稳定下来

    非静态嵌套类显示了一点额外的开销,但存在一些对齐(例如,删除它们的成员,或添加不是像字节数组这样的独立对象的较小基本体成员)


    当然,我们从中没有学到什么有用的东西。真正的问题是,你为什么问这个?事实上,你问的是一个红旗,表明你问的问题是错误的。

    这到底是什么意思?创建两个问题的示例,检查使用的堆空间量,然后将示例和结果发布回此处。嵌套类可能需要更多的字节,由于必须维护这两个类之间的关系。如果
    Door
    Car
    的静态嵌套类,
    Door
    对象不会比
    Door
    是另一个顶级类占用更多内存。@user590849:更重要的是,你为什么要问这个问题?你问这个问题的事实是一个危险信号,表明你问的问题是错误的。我为什么问这个?好的,就像我在问题中说的-我只是想知道。有关具体测量对象大小的一些好方法,请参阅(instrumentation package将为您提供比此测试更详细的信息)。Nested稍大一些,因为它包含对包含类的引用。非常感谢您进行此基准测试。我一直在想这个问题。小更正:局部变量位于堆栈上(原语和引用,当然不是引用指向的实际对象)。通过
    new
    构造对象时,非静态原语字段最终会出现在堆上,并且是对象的封装外形的一部分。我相信静态原语/引用字段也在堆上,但我不记得了。
    separate:      10320000 each=1032
    nested:        10400000 each=1040
    static nested: 10320000 each=1032
    
    separate:      160000 each=16
    nested:        160000 each=16
    static nested: 160000 each=16