`

java.lang.OutOfMemoryError引来的一系列之Java字节码操控

    博客分类:
  • J2EE
阅读更多
上一篇BLOG中总结了对Java内存管理的认识http://japi.iteye.com/blog/261626
还http://japi.iteye.com/blog/260196中写了几个引起OutOfMemoryError:PermGen space原因:
引用
可以有以下几个方面的原因:

1,使用了proxool,因为proxool内部包含了一个老版本的cglib.

2, log4j,最好不用,只用common-logging

3, 老版本的cglib,快点更新到最新版。

4,更新到最新的hibernate3.2

对于cglib得再关注下.
先看看资料
http://www.blogjava.net/calvin/archive/2005/11/28/21741.html
http://www.iteye.com/topic/98178
http://www.ibm.com/developerworks/cn/java/j-lo-asm30/#N10200
http://www.cnjm.net/tech/article1219.html

CGLIB上手很简单,但功能相当强大.
引用
CGLIB是一个强大的高性能的代码生成包。它广泛的被许多AOP的框架使用,例如Spring AOP和dynaop,为他们提供方法的interception(拦截)。最流行的OR Mapping工具hibernate也使用CGLIB来代理单端single-ended(多对一和一对一)关联(对集合的延迟抓取,是采用其他机制实现的)。EasyMock和jMock是通过使用模仿(moke)对象来测试java代码的包。它们都通过使用CGLIB来为那些没有接口的类创建模仿(moke)对象。


引用
CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。除了CGLIB包,脚本语言例如Groovy和BeanShell,也是使用ASM来生成java的字节码。当不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括 class文件的格式和指令集都很熟悉

ASM何许人也?
引用
ASM 是一个 Java 字节码操控框架。它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。


感觉ASM与CGLIB的关系有点像LUCENE与COMPASS,JDBC与SPRING中的JdbcTemplate一样,简化了编程难度,方便使用.

看看CGLIB的实现
public class MyClass {
    public void method() {
        System.out.println("MyClass.method()");
    }
}

import java.lang.reflect.Method;
 
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodProxy;
import net.sf.cglib.proxy.MethodInterceptor;
 
public class Main implements MethodInterceptor{
 
    public static void main(String[] args) {
 
        Enhancer enhancer = new Enhancer();
        //在这代理了 
        enhancer.setSuperclass(MyClass.class);
        enhancer.setCallback(new Main());
 
        // 创造 代理 (动态扩展了MyClass类)
        MyClass my = (MyClass)enhancer.create();
 
        my.method();
    }
    public Object intercept(Object obj, 
                                Method method, 
                                Object[] args, 
                                MethodProxy proxy) throws Throwable {
 
            System.out.println(obj.getClass().getName());
 			
            proxy.invokeSuper(obj, args);
 
            return null;
        }
}

在运行以上程序的时候不仅得加入cglib包还得加入ASM包,更得注意兼容问题.直接使用spring或者hibernate包中就可以.
这个类似与Java的动态代理,但优于动态代理,动态代理以接口为基础,而CGLIB可面向类实现.
CGLIB其实就是动态地创建了一个代理类的子类,扩充了功能.
引用
Hibernate主要是利用cglib生成pojo的子类并override get方法来实现lazy loading机制,Spring则是利用cglib来实现动态代理

----------------------------------------------------------------------
CGLIB的简易使用和强大的功能,关键得力于ASM.ASM直接操控class文件.
Java 类文件

ASM中运用了PUSH模型(Vistor模式),适配器以及Chain-of-responsibility模式.
引用
因为需要处理字节码结构是固定的,所以不需要专门抽象出一种 Vistable 接口,而只需要提供 Visitor 接口。所谓 Visitor 模式和 Iterator 模式有点类似,它们都被用来遍历一些复杂的数据结构。Visitor 相当于用户派出的代表,深入到算法内部,由算法安排访问行程。Visitor 代表可以更换,但对算法流程无法干涉,因此是被动的,这也是它和 Iterator 模式由用户主动调遣算法方式的最大的区别。


也可对比下别的字节码操控库:
BCEL
http://www-128.ibm.com/developerworks/cn/java/j-dyn0414/index.html

2
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics