我一直在玩jmap,发现简单的"Hello World"Java程序创建了数千个对象.以下是Oracle JVM update 131在启动时创建的截断对象列表:
num #instances #bytes class name
----------------------------------------------
1: 402 4903520 [I
2: 1621 158344 [C
3: 455 52056 java.lang.Class
4: 194 49728 [B
5: 1263 30312 java.lang.String
6: 515 26088 [Ljava.lang.Object;
7: 115 8280 java.lang.reflect.Field
8: 258 4128 java.lang.Integer
9: 94 3760 java.lang.ref.SoftReference
10: 116 3712 java.util.Hashtable$Entry
11: 126 3024 java.lang.StringBuilder
12: 8 3008 java.lang.Thread
13: 74 2576 [Ljava.lang.String;
14: 61 1952 java.io.File
15: 38 1824 sun.util.locale.LocaleObjectCache$CacheEntry
16: 12 1760 [Ljava.util.Hashtable$Entry;
17: …Run Code Online (Sandbox Code Playgroud) 我有一点奇怪的要求.我猜.
我想使用我创建的自定义代理来装饰实现特定接口的所有对象,但我需要这对代码本身是透明的.可以包含在构建过程中的东西将是完美的.
我在AOP中思考但没有看到这样的能力,我正在寻找想法,甚至是疯狂的想法.我正在考虑在编译之后更改源代码并重新编译它至少替换直接调用new(我想这不会通过反射创建对象但是会是一个很好的开始)但是我可以想到一百万个问题这可能会带来,打破我的主要目标,即使这种仪器尽可能透明.
你们有些人对这种不寻常的事情有过一些经验吗?
问候
我需要使用AspectJ为每个初始化对象注入几个方法.
我想用这个:
pointcut vistaInjection(Object o)
: initialization(java.lang.Object.new() )
&& target(o)
&& !within(objectAspect);
before(Object o): methodInjection(o){System.err.println("INIT");}
Run Code Online (Sandbox Code Playgroud)
切入点对象的初始化,所以我可以将这些方法直接注入到作为每个其他对象一部分的对象中.
但是,它不起作用.你知道为什么吗?或者可能是另一种方式如何100%确定每个初始化对象都是切入点?*.new不适用于字符串,列表和其他内容.
谢谢!
这是注释:
@Target(value = ElementType.TYPE)
@Retention(value = RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnotation {
String name();
}
Run Code Online (Sandbox Code Playgroud)
这是一个带注释的类:
@MyAnnotation(name="foo")
public class ClassA {
public ClassA() {
// Do something
}
}
Run Code Online (Sandbox Code Playgroud)
这是第二个带注释的类:
@MyAnnotation(name="bar")
public class ClassB {
public ClassB(String aString) {
// Do something
}
}
Run Code Online (Sandbox Code Playgroud)
我正在寻找一个aspectj切入点,正确匹配ClassA和ClassB的构造函数,而不匹配任何其他未注释的类的构造函数MyAnnotation.