如何检测Java字节码(FindBugs)中的数组大小
我想通过查看字节码来了解正在分配的数组的大小,当然,如果这些信息在编译时已知的话 背景:我想编写一个FindBugs检测器(它查看编译后的字节码)并报告数组分配的某些情况。为了滤除误报,我对“小”数组不感兴趣,只对编译时大小不可用或大于可配置阈值的数组感兴趣如何检测Java字节码(FindBugs)中的数组大小,java,arrays,static-analysis,bytecode,findbugs,Java,Arrays,Static Analysis,Bytecode,Findbugs,我想通过查看字节码来了解正在分配的数组的大小,当然,如果这些信息在编译时已知的话 背景:我想编写一个FindBugs检测器(它查看编译后的字节码)并报告数组分配的某些情况。为了滤除误报,我对“小”数组不感兴趣,只对编译时大小不可用或大于可配置阈值的数组感兴趣 由于FindBugs源代码没有太多的文档记录,我正在寻找一些关于如何开始的指针-可能已经有一个Detector在做类似的事情,我可以看看。好的,如果它们是基于常量分配的,您可以检查在分配之前推送的常量。例如: class ArraySize
由于FindBugs源代码没有太多的文档记录,我正在寻找一些关于如何开始的指针-可能已经有一个Detector在做类似的事情,我可以看看。好的,如果它们是基于常量分配的,您可以检查在分配之前推送的常量。例如:
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
}
从“ArraySize.java”编译而来
类ArraySize扩展了java.lang.Object{
排列();
代码:
0:aload_0
1:invokespecial#1;//方法java/lang/Object。“:()V
4:返回
公共静态void main(java.lang.String[]);
代码:
0:bipush 10
2:newarray int
4:astore_1
5:sipush 1000
8:newarray int
10:astore_2
11:返回
}
这可能会有点棘手。我的知识是不完整的,但您至少需要注意三种指令(NEWARRAY、ANEWARRAY和MULTIANEWARRAY)。查看上一条指令(或者在MULTIANEWARRAY的情况下,n条上一条指令)可以获得大小,根据大小,即使它是一个常量,也可能会加载BIPUSH、SIPUSH或LDC(任何其他?)。正如您所注意到的,如果类是计算的结果,您可能会无限期地追溯指令
如果我没记错的话,FindBugs在内部使用BCEL,但我从来没有仔细研究过它们到底有多聪明。如果这两个团队中的任何一个都有合适的邮件列表,那么他们可能会被证明是一个更好的询问地点——他们可能至少知道是否有人曾经走过这条路。谢谢,这已经是一个开始了。在您的示例中,它将内联常量。当你有像int x=10这样的东西时,它会变得更加棘手;新字节[5+x];尽管15是明显的结果,但这取决于编译器(及其设置),可能会在新分配之前在堆栈上完成计算。我想知道,在FindBugs中是否有一个标准的方法来达到这个目的。我不知道FindBugs的内部,对不起;我只知道一点字节码。