我想通过查看字节码来了解分配的数组的大小,当然,如果该信息在编译时是已知的。
背景:我想编写一个 FindBugs 检测器(它查看已编译的字节码)并报告某些数组分配的发生。为了过滤掉误报,我对“小”数组不感兴趣,而只对那些大小在编译时不可用或大于可配置阈值的数组感兴趣。
由于 FindBugs 源代码没有太多的文档记录,我正在寻找一些关于如何开始的指示——也许已经有一个检测器在做类似的事情,我可以看看。
我想通过查看字节码来了解分配的数组的大小,当然,如果该信息在编译时是已知的。
背景:我想编写一个 FindBugs 检测器(它查看已编译的字节码)并报告某些数组分配的发生。为了过滤掉误报,我对“小”数组不感兴趣,而只对那些大小在编译时不可用或大于可配置阈值的数组感兴趣。
由于 FindBugs 源代码没有太多的文档记录,我正在寻找一些关于如何开始的指示——也许已经有一个检测器在做类似的事情,我可以看看。
好吧,如果它们是基于常量分配的,您可以检查在分配之前推送的常量。例如:
class ArraySize {
private static final int smallsize = 10;
private static final int largesize = 1000;
public static void main(String[] args) {
int[] small = new int[smallsize];
int[] big = new int[largesize];
}
}
给出字节码:
Compiled from "ArraySize.java"
class ArraySize extends java.lang.Object{
ArraySize();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: bipush 10
2: newarray int
4: astore_1
5: sipush 1000
8: newarray int
10: astore_2
11: return
}
这可能会有点棘手。我的知识不完整,但您至少需要注意三种指令(NEWARRAY、ANEWARRAY 和 MULTINEWARRAY)。查看前面的指令(或者在 MULTIANEWARRAY 的情况下,n前面的指令)得到大小,即使它是一个常量,也可能根据大小加载 BIPUSH、SIPUSH 或 LDC(其他什么?)。正如您所指出的,如果该类是计算的结果,您可能会无限期地追溯指令。
如果我没记错的话,FindBugs 在内部使用了 BCEL,但我从来没有在那里挖掘过它们究竟有多聪明。如果这些团队中的任何一个有适当的邮件列表,他们可能会证明是一个更好的地方问 - 他们可能至少会知道是否有人曾经走过这条路。