Java方法区溢出

博客围绕Java方法区溢出展开,方法区存放Class相关信息,可通过运行时产生大量类使其溢出,本次试验用CGLIB生成动态类。Spring、Hibernate等框架增强类时会用字节码技术,需更大方法区。还提及常见溢出场景,给出定位JVM参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java方法区溢出

方法区用于存放Class的相关信息,如:类名,访问修饰符,常量池,字符描述,方法描述等。对于这个区域的测试,基本思路是运行时产生大量的类去填满方法区,直到溢出。虽然直接使用Java SE API也可以动态产生类(如反射时的GeneratedConstructorAccessor和动态代理等),但在本次试验使用CGLIB直接操作字节码运行时,生成大量的动态类。

值得注意的是,当前主流的很多框架 如:Spring,Hibernate对类进行增强时,都会使用到类似CGLIB这类字节码技术,增强的类越多,就需要越大的方法区来保证动态生成的Class可以加载入内存。例如:

import java.lang.reflect.Method;  
  
import net.sf.cglib.proxy.Enhancer;  
import net.sf.cglib.proxy.MethodInterceptor;  
import net.sf.cglib.proxy.MethodProxy;  
/** 
 * VM args -XX:PermSize=10M -XX:MaxPermSize=10M 
 * 
 */  
public class JavaMethodAreaOOM {  
    public static void main(String[] args) {  
        while (true) {  
            Enhancer enhancer = new Enhancer();  
            enhancer.setSuperclass(OOM.class);  
            enhancer.setUseCache(false);  
            enhancer.setCallback(new MethodInterceptor() {  
  
                @Override  
                public Object intercept(Object obj, Method arg1, Object[] args, MethodProxy proxy) throws Throwable {  
                    return proxy.invokeSuper(obj, args);  
                }  
            });  
            OOM oom = (OOM) enhancer.create();  
            oom.sayHello("Kevin LUAN");  
        }  
    }  
  
    static class OOM {  
        public String sayHello(String str) {  
            return "HI " + str;  
        }  
    }  
}  
Caused by: java.lang.OutOfMemoryError:PermGen space
JDK 1.7 64位运行结果如下:
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
Exception in thread "main" 
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"

方法区溢出也是一种常见的内存溢出异常,一个类如果要被垃圾回收器回收掉,判定条件非常苛刻,在经常动态生成大量Class的应用中,需要特别注意类的回收状况。这类场景除了上面提到的程序使用GCLIB字节码增强外,常见的还用JSP或动态产生JSP文件的应用(JSP第一次运行时需要编译为JAVA类),基于OSGI的应用(即使是同一个类文件,被不同的加载器加载也会视为不同的类)等。

#增加JVM 参数来快速定位下 Class load ,来定位下。

-XX:+TraceClassLoading -XX:+TraceClassUnloading

输出格式:[Loaded sun.rmi.server.LoaderHandler from /usr/local/java/jdk1.7.0/jre/lib/rt.jar]可以方便定位出增加的CLASS文件来源

### Element Plus 的 `el-table` 组件隐藏表头方法 在使用 Element Plus 的 `el-table` 组件时,如果希望隐藏表头,可以通过设置 CSS 样式来实现这一需求。具体来说,在定义表格样式时可以利用 `.hidden-header` 类名,并通过覆盖默认样式的方式使表头不可见。 对于 Vue 3 和 Element Plus 结合使用的场景下,可以在模板部分为 `<el-table>` 添加自定义类名以便于样式控制: ```html <template> <div> <!-- 使用 hiddenHeaderClass 来应用特定样式 --> <el-table :data="tableData" class="hidden-header"> <el-table-column prop="date" label="日期"></el-table-column> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="address" label="地址"></el-table-column> </el-table> </div> </template> <script setup> import { ref } from 'vue'; const tableData = ref([ { date: '2016-05-03', name: 'Tom', address: 'No. 189, Grove St, Los Angeles' }, // ...其他数据项... ]); </script> <style scoped> /* 定义用于隐藏表头的CSS */ .hidden-header ::v-deep th.el-table__cell.is-leaf, .hidden-header ::v-deep .el-table__header-wrapper tr:first-child th { display: none; } </style> ``` 上述代码片段展示了如何创建一个带有隐藏表头样式的 `el-table` 实例[^1]。需要注意的是,这里采用了 `::v-deep` 深度选择器来穿透作用域以影响内部组件样式;另外,`.is-leaf` 及其子元素的选择是为了确保只针对实际显示的数据列进行操作而不干扰分组或其他特殊类型的头部单元格。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值