最近组内项目报了一个错,大概原因就是元空间的问题。虽然问题解决了,但是对于作者来说感觉还是一头雾水,为啥一头雾水?因为我们知道元空间在java8中替代的是java7中的永久代,永久代就是存储类信息,我们用到的类都要存放到这块空间。但是在java8中元空间在堆外。那么元空间的出错就成了容量太小装不下项目运行所需要的类?那么又是何种原因导致项目会不断生成新的类?我们知道java的动态代理会生成代理类,代理类的特点就是类名后边很多莫名其妙的字符。所以我们的元空间导致的问题很大原因上还是使用了动态代理。而且这些动态代理类被无限的生成了并且没有来得及被卸载,或者被卸载了但是其生成的对象还在。
那么咋实现一下如何让元空间溢出吧。
编写一段代码:
@RestController
@RequestMapping("/v")
public class UserController {
Logger logger= LoggerFactory.getLogger(UserController.class);
@Autowired
private ThreadService threadService;
@GetMapping(value = "/test")
public String TEST(){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(User.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
return proxy.invoke(obj, args);
}
});
Object o=enhancer.create();
System.out.println(o.toString());
User user=threadService.getUser();
logger.info(user.toString());
user.setUserName("1");
return "success";
}
}
设置元空间大小100M
使用jmeter发送接口,设置100个线程,每秒100次请求,轮询10000次。
使用java visualVm进行载入类数量和元空间变化情况。
查看报错日志:
切断jmeter连接中断报错。
小结:通过上述代码,我们可以得出的结论就是我们编写对访问量有要求的系统的时候要主要避免采用动态代理。至于我们组项目线上的报错本人还没研究透彻,虽然解决了问题。但是也匪夷所思,就到这里吧,等研究透了再写文章,OK晚安。