反射如何影响Perm的大小?

时间:2009-12-01 12:22:14

标签: java reflection memory-management

我理解perm大小用于存储元数据,包括字节代码,静态内容等。

我的问题是如何使用反射影响烫发大小。 我的意思是如果 Program-A 使用正常运行方式的方式而 Program-B 全部使用反射,两个程序的perm大小将如何比较< /强>

4 个答案:

答案 0 :(得分:7)

当您执行加载新类内化字符串的代码时,perm空间将会增长。必须加载反射类,这是肯定的。我不确定反射API是否确实使用了内部化的字符串,但它不应该很难找到。

例如,对于方法getDeclaredMethod(String name, Class<?>... parameterTypes),name参数将被内化。

这个片段很好地填补了烫发空间:

Random random = new Random();
while(true){
    try {
        X.class.getDeclaredMethod(toBinaryString(random.nextLong()));
    } catch (Exception e) {
    }
}

alt text http://img4.imageshack.us/img4/9725/permgen.jpg

在实际应用中,它没有任何区别。

答案 1 :(得分:3)

我不完全确定我理解这个问题,但Java类已经包含了对它们进行反射所需的一切。 .class文件不会根据其使用方式而改变。

编辑1:提供一些更具体的例子,以更好地区分我们所讨论的“反思”类型。

示例:

class Foo {
    public void bar() {
        System.out.println( "Hello, world." );
    }
}

// Conventional calling
Foo f = new Foo();
foo.bar();

// Reflection based callling
Class fooClass = Class.forName( "Foo" );
Method m = fooClass.getMethod( "bar", null );
Object f = fooClass.newInstance();
m.invoke( m, null );     

在传统的调用情况下,将加载Foo.class及其任何直接类依赖项。酒吧将被执行。字符串“Foo”和“bar”已经作为调用类的一部分被实现,因为字节代码在运行时使用字符串来解析类和方法。 (实际上“bar”将是完整的方法签名,所以实际上比“bar”更长)

在反思案例中,完全相同的事情发生了。加载的唯一附加类是Method.class。这应该是对烫发大小的唯一影响。

后一种情况具有性能影响。方法查找相对昂贵,因此建议尽可能缓存Method对象。对调用的额外方法调用具有轻微的性能影响,因为它是一个额外的方法调用。热点将通过此次通话进行优化...至少比正常情况更多。 JITing完全相同。

编辑2:注意在反射期间加载的一些其他对象......

java.lang.Class将在访问时创建和缓存Method对象(或Field对象等)。它们被缓存在SoftReference中,因此如果内存使用需要它,它将被回收。

但是,这些对象的初始化意味着VM可能会加载其他内部字符串以支持创建这些Method对象。我的猜测是这些字符串可能已经是反射类常量池的一部分,但它们可能不是。无论哪种方式,每个类每个方法,每个类每个字段等都有一次点击。访问方法,你至少会获得这些方法的所有名称。访问这些字段,您将获得这些字段的名称。

答案 2 :(得分:3)

Reflection可以生成类,具体取决于实现。例如,在编译为字节码之前,您可能需要使用反射工件数千次。

与以往一样,建议是:在现实情况下描述您的代码。

答案 3 :(得分:2)

第一个答案基本上是正确的 - 一个类是“正常”加载还是通过反射加载没有区别。无论哪种方式,它都被加载了。我不知道我所知道的实习字符串有什么不同。

我认为有一个更间接的影响:使用反射,可能会导致更少的类加载。假设您有一些代码可以根据某些参数加载100个类中的一个。在没有反射的情况下编写它,您将导入所有100个类并实例化其中一个类。

使用反射,只会加载1个类。如果没有,在加载此代码的类时,将加载所有100个导入的类,因为所有类都被引用。因此,更多的类被加载到烫发空间。

但这是一个有点人为的例子。除非它真的描述了你的情况,否则我想你会注意到几乎没有区别。也就是说,在你确定这不是微不足道之前,不要让这影响你的设计决定。