温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何优化内存

发布时间:2021-10-25 14:54:08 阅读:120 作者:iii 栏目:编程语言
开发者测试专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>

这篇文章主要讲解了“如何优化内存”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何优化内存”吧!

案例介绍

这里,我将在平时工作过程中总结的内存溢出的情况,以代码案例的形式直观的分享给大家,希望能够为小伙伴们带来实质性的帮助。

接下来,我们就以代码案例的形式来分析各种内存溢出的情况。

 

定义主类结构

首先,我们创建一个类叫做BlowUpJVM,所有的案例实验都是基于这个类进行。

public class BlowUpJVM {  } 
   

栈深度溢出

public static void  testStackOverFlow(){       BlowUpJVM.testStackOverFlow(); } 
 

栈不断递归,而且没有处理,所以虚拟机栈就不断深入不断深入,栈深度就这样溢出了。

 

永久代内存溢出

public static void testPergemOutOfMemory1(){    //方法一失败     List<String> list = new ArrayList<String>();     while(true){       list.add(UUID.randomUUID().toString().intern());    } } 
 

打算把String常量池堆满,没想到失败了,JDK1.7后常量池放到了堆里,也能进行垃圾回收了。

然后换种方式,使用cglib,用Class把老年代取堆满

public static void testPergemOutOfMemory2(){    try {       while (true) {          Enhancer enhancer = new Enhancer();          enhancer.setSuperclass(OOM.class);          enhancer.setUseCache(false);          enhancer.setCallback(new MethodInterceptor() {             @Override             public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {                return proxy.invokeSuper(obj, args);             }          });          enhancer.create();       }    }    catch (Exception e){       e.printStackTrace();    } } 
 

虚拟机成功内存溢出了,那JDK动态代理产生的类能不能溢出呢?

public static void testPergemOutOfMemory3(){    while(true){    final OOM oom = new OOM();    Proxy.newProxyInstance(oom.getClass().getClassLoader(), oom.getClass().getInterfaces(), new InvocationHandler() {          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {             Object result = method.invoke(oom, args);             return result;          }       });    } } 
 

事实表明,JDK动态代理差生的类不会造成内存溢出,原因是:JDK动态代理产生的类信息,不会放到永久代中,而是放在堆中。

 

本地方法栈溢出

public static void testNativeMethodOutOfMemory(){    int j = 0;    while(true){       Printer.println(j++);       ExecutorService executors = Executors.newFixedThreadPool(50);       int i=0;       while(i++<10){          executors.submit(new Runnable() {             public void run() {             }          });       }    } } 
 

这个的原理就是不断创建线程池,而每个线程池都创建10个线程,这些线程池都是在本地方法区的,久而久之,本地方法区就溢出了。

 

JVM栈内存溢出

public static void testStackOutOfMemory(){     while (true) {               Thread thread = new Thread(new Runnable() {                      public void run() {                           while(true){                       }                    }               });               thread.start();        }   } 
 

线程的创建会直接在JVM栈中创建,但是本例子中,没看到内存溢出,主机先挂了,不是JVM挂了,真的是主机挂了,无论在mac还是在windows,都挂了。

温馨提示,这个真的会死机的。

 

堆溢出

public static void testOutOfHeapMemory(){    List<StringBuffer> list = new ArrayList<StringBuffer>();    while(true){       StringBuffer B = new StringBuffer();       for(int i = 0 ; i < 10000 ; i++){          B.append(i);       }       list.add(B);    } } 

不断往堆中塞新增的StringBuffer对象,堆满了就直接溢出了。

感谢各位的阅读,以上就是“如何优化内存”的内容了,经过本文的学习后,相信大家对如何优化内存这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

原文链接:https://my.oschina.net/bingheteam/blog/4704185

AI

开发者交流群×