使用嵌套的最终块制作巨大的StackMapTable非常容易,因为javac不明智地为每个嵌套级别生成单独的变量。这允许从非常简单的方法产生几兆字节,如下所示:
class A {{
int a;
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
a=0;
}}}}}}}}}}}}
}}
无法添加更多嵌套级别,因为单个方法的代码大小将超过代码大小。您还可以使用实例初始值设定项复制到每个构造函数的事实来复制此内容:
class A {{
int a;
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
a=0;
}}}}}}}}}}}}
}
A() { }
A(int a) { }
A(char a) { }
A(double a) { }
A(float a) { }
A(long a) { }
A(short a) { }
A(boolean a) { }
A(String a) { }
A(Integer a) { }
A(Float a) { }
A(Short a) { }
A(Long a) { }
A(Double a) { }
A(Boolean a) { }
A(Character a) { }
}
这个简单的java文件在使用Java 8 javac编译时会产生105,236,439字节.class文件。您还可以添加更多构造函数,尽管存在javac失败的风险(用于克服这一点)。OutOfMemoryError
javac -J-Xmx4G