java代码留后门 java代码放在哪里( 二 )


*/
public static long sizeOf(Object o) {
if(inst == null) {
throw new IllegalStateException("Can not access instrumentation environment.\n" +
"Please check if jar file containing SizeOfAgent class is \n" +
"specified in the java's \"-javaagent\" command line argument.");
}
return inst.getObjectSize(o);
}
}
步骤2:上面我们写好了agent的代码,此时我们要将上面这个类编译后打包为一个jar文件,并且在其包内部的META-INF/MANIFEST.MF文件中增加一行:Premain-Class: MySizeOf代表执行代理的全名,这里的类名称是没有package的,如果java代码留后门你有package,那么就写全名,我们这里假设打包完的jar包名称为agent.jar(打包过程这里简单阐述,就不细说了),OK,继续向下走:
步骤3:编写测试类,测试类中写:
public class TestSize {
public static void main(String []args) {
System.out.println(MySizeOf.sizeOf(new Integer(1)));
System.out.println(MySizeOf.sizeOf(new String("a")));
System.out.println(MySizeOf.sizeOf(new char[1]));
}
}
下一步准备运行,运行前我们准备初步估算下结果是什么,目前我是在32bit模式下运行jvm(注意,不同位数的JVM参数设置不一样,对象大小也不一样大) 。
(1) 首先看Integer对象,在32bit模式下 , class区域占用4byte,mark区域占用最少4byte,所以最少8byte头部,Integer内部有一个int类型的数据,占4个byte , 所以此时为8+4=12,java默认要求按照8byte对象对其 , 所以对其到16byte,所以我们理论结果第一个应该是16java代码留后门;
(2) 再看String,长度为1,String对象内部本身有4个非静态属性(静态属性我们不计算空间,因为所有对象都是共享一块空间的),4个非静态属性中,有offset、count、hash为int类型,分别占用4个byte,char value[]为一个指针,指针的大小在bit模式下或64bit开启指针压缩下默认为4byte,所以属性占用了16byte , String本身有8byte头部,所以占用了24byte;其次,一个String包含了子对象char数组,数组对象和普通对象的区别是需要用一个字段来保存数组的长度,所以头部变成12byte , java中一个char采用UTF-16编码,占用2个byte,所以是14byte , 对其到16byte,24+16=40byte;
(3) 第三个在第二个基础上已经分析 , 就是16byte大?。?
也就是理论结果是:16、40、16;
步骤4:现在开始运行代码:运行代码前需要保证classpath把刚才的agent.jar包含进去:
D:javac TestSize.java
D:java -javaagent:agent.jar TestSize
16
24
16
第一个和第三个结果一致了,不过奇怪了,第二个怎么是24,不是40,怎么和理论结果偏差这么大,再回到理论结果中 , 有一个24曾经出现过 , 24是指String而不包含char数组的空间大小,那么这么算还真是对的,可见,java默认提供的方法只能测量对象当前的大小,如果要测量这个对象实际的大?。ㄒ簿褪前俗佣韵螅?那么就需要自己写算法来计算了,最简单的方法就是递归,不过递归一项是我不喜欢用的 , 无意中在一个地方看到有人用栈写了一个代码写得还不错 , 自己稍微改了下,就是下面这种了) 。
import java.lang.instrument.Instrumentation;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Stack;
public class MySizeOf {
static Instrumentation inst;
public static void premain(String agentArgs, Instrumentation instP) {
inst = instP;
}
public static long sizeOf(Object o) {

推荐阅读