Fix metaspace OOM problem when trace large method (#1511)

This commit is contained in:
gongdewei
2020-09-18 18:35:34 +08:00
committed by GitHub
parent fe84834880
commit 1f9f7d6e5d
2 changed files with 23 additions and 5 deletions
@@ -55,9 +55,24 @@ public class AsmUtils {
return result;
}
public static byte[] toBytes(ClassNode classNode, ClassLoader classLoader) {
ClassWriter writer = new ClassLoaderAwareClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS,
classLoader);
public static ClassReader toClassNode(byte[] classBytes, ClassNode classNode) {
ClassReader reader = new ClassReader(classBytes);
reader.accept(classNode, ClassReader.SKIP_FRAMES);
return reader;
}
/**
* Generate class bytes from class node.
* <br>
* <B>NOTE: must pass origin classReader for bytecode optimizations, avoiding JVM metaspace OOM.</B>
* @param classNode
* @param classLoader
* @param classReader origin class reader
* @return
*/
public static byte[] toBytes(ClassNode classNode, ClassLoader classLoader, ClassReader classReader) {
int flags = ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS;
ClassWriter writer = new ClassLoaderAwareClassWriter(classReader, flags, classLoader);
classNode.accept(writer);
return writer.toByteArray();
}
@@ -21,6 +21,7 @@ import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import com.alibaba.arthas.deps.org.objectweb.asm.ClassReader;
import com.alibaba.arthas.deps.org.objectweb.asm.Opcodes;
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
import com.alibaba.arthas.deps.org.objectweb.asm.tree.AbstractInsnNode;
@@ -122,7 +123,9 @@ public class Enhancer implements ClassFileTransformer {
return null;
}
ClassNode classNode = AsmUtils.toClassNode(classfileBuffer);
//keep origin class reader for bytecode optimizations, avoiding JVM metaspace OOM.
ClassNode classNode = new ClassNode(Opcodes.ASM8);
ClassReader classReader = AsmUtils.toClassNode(classfileBuffer, classNode);
// remove JSR https://github.com/alibaba/arthas/issues/1304
classNode = AsmUtils.removeJSRInstructions(classNode);
@@ -230,7 +233,7 @@ public class Enhancer implements ClassFileTransformer {
classNode.version = Opcodes.V1_5;
}
byte[] enhanceClassByteArray = AsmUtils.toBytes(classNode, inClassLoader);
byte[] enhanceClassByteArray = AsmUtils.toBytes(classNode, inClassLoader, classReader);
// 增强成功,记录类
classBytesCache.put(classBeingRedefined, new Object());