美文网首页Java
内存又溢出了?这不得背锅了啊

内存又溢出了?这不得背锅了啊

作者: 狼王编程 | 来源:发表于2020-11-09 10:09 被阅读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对象,堆满了就直接溢出了。

留言区

Garnett的Java之路 发起了一个读者讨论 那么问题来了,你遇到过内存溢出吗?

乐于输出干货的Java技术公众号:Garnett的Java之路。公众号内有大量的技术文章、海量视频资源、精美脑图,不妨来关注一下!回复【资料】领取大量学习资源和免费书籍!

相关文章

  • 内存又溢出了?这不得背锅了啊

    写在前面 相信小伙伴们在平时工作的过程中,或多或少都会遇到一个场景:内存溢出。如果你没有遇到过这个场景,那就说明你...

  • 爷爷又背锅了

    还记得以前读书的时候,跟爸爸闲聊,跟他说起同学某某如何如何,爸爸就扬言自己会看相,让我随便报同学的名字,他就能说出...

  • 清迈流水-3

    下过雨后的清迈, 晚上还是很适宜的, 就是出了几身汗。 还好, 柒锅锅公寓的乳胶枕不吸汗, 啊~ 不得不说, 这枕...

  • 这锅,得背

    无意中捡到一口锅,便往里装了许多宝贝,然后拧紧锅盖,用绳子捆起来小心翼翼的背在背上。约莫走了很远了,记不大清了,但...

  • 这锅谁来背?

    宝强一纸声明将老宋推到了风口浪尖,能量满满的网友哪怕是在凌晨将眠时分,依旧以最快的速度成立四十万水军,辗转...

  • XX的权力的权力

    任何一个XX的权力机关,有个最大的好处,就是出了问题,或者事情没有按照设想的发展,总会有帮他们背锅的。 这背锅的,...

  • 搭个平台也不是那么好弄的

    割韭菜还是最好的办法,没有比这更好的方法了。 锅总是要有人背的。 努力!不要成为背锅侠。

  • 辣椒“这锅我不背了!”

    从辣八的祖祖代代 四大姑五大姨六大叔的口中得知 我们辣椒一族一直以来 蒙受了许许多多的冤屈 有损我们的种族清誉 严...

  • 友情淡了,这锅谁来背

    昨晚又收到一个学妹的私信,说跟以前的朋友感情淡了很多,因为距离的疏远,而在大学却总交不到无话不谈的好友。 我这样开...

  • 垃圾分类

    招谁惹谁,弄个垃圾分类,猪又背锅了。

网友评论

    本文标题:内存又溢出了?这不得背锅了啊

    本文链接:https://www.haomeiwen.com/subject/gmclbktx.html