package test;
import java.io.*;
import java.util.*;
//内存溢出测试
public class OOM {
public void heapOOM(){//堆内存溢出
// List<int[]>list=new LinkedList<int[]>();
// while(true){
// list.add(new int[1024]);//不断创造可存活的对象
// }
ByteClassLoader loader=new ByteClassLoader();
javaClass java=javaClass.open("bin\\test\\OOM.class");
List<Class<?>>list=new LinkedList<Class<?>>();
for(int j=0;true;j++){
java.replaceName("OOM"+j);
//Perm区内存溢出
Class<?>clazz=loader.load(java.getClassByte());
list.add(clazz);
Object obj=null;
try {
obj=clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println(obj);
}
}
}
class ByteClassLoader extends ClassLoader{
public Class<?>load(byte[]classByte){
return defineClass(null, classByte, 0, classByte.length);
}
}
class javaClass{
private byte[]javaClassByte;
public javaClass(byte[]classByte){
javaClassByte=classByte;
}
public String getClassName(){//获取字节流的类的名
int classNameOff=0x10;//类名偏移位置
int nameLengthOff=0x0e;//类名字节长度偏移,两个字节的数表示长度
int length=(javaClassByte[nameLengthOff]&0xff)<<8;
length+=(0xff&javaClassByte[nameLengthOff+1]);
String name=new String(javaClassByte,classNameOff,length);
return name;
}
public void replaceName(String newName){//以新类名替换旧类名
String oldName=getClassName();//旧类名
int nlength=newName.length();//新类名的长度
int olength=oldName.length();//旧类名的长度
byte[]temp=new byte[javaClassByte.length-olength+nlength];
//将类名长度偏移位置之前字节复制到新字节流中
System.arraycopy(javaClassByte, 0, temp, 0, 0x0e);
temp[0x0e]=(byte)(nlength>>8);//填写新的类名长度值
temp[0x0f]=(byte)nlength;
//填写新类名
System.arraycopy(newName.getBytes(), 0, temp, 0x10, nlength);
//复制其余字节到新字节中
System.arraycopy(javaClassByte, 0x10+olength,
temp,0x10+nlength ,javaClassByte.length-0x10-olength);
javaClassByte=temp;
}
public byte[]getClassByte(){
return javaClassByte;
}
public static javaClass open(String file){//打开类文件file
FileInputStream fis=null;
try {
fis = new FileInputStream(new File(file));
byte[]temp=new byte[fis.available()];
fis.read(temp);
return new javaClass(temp);
} catch (Exception e) {
return null;
} finally {
if(fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
让Java虚拟机Perm区内存溢出的方法
最新推荐文章于 2021-02-27 13:38:43 发布