【性能优化】纳尼?内存又溢出了?!是时候总结一波了!!

存储 存储软件
相信小伙伴们在平时工作的过程中,或多或少都会遇到一个场景:内存溢出。如果你没有遇到过这个场景,那就说明你是个假的程序员。哈哈,开个玩笑,平时工作过程中,我们确实会遇到这个问题。

[[350499]]

 作者个人研发的在高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。自开源半年多以来,已成功为十几家中小型企业提供了精准定时调度方案,经受住了生产环境的考验。为使更多童鞋受益,现给出开源框架地址:https://github.com/sunshinelyz/mykit-delay

写在前面

相信小伙伴们在平时工作的过程中,或多或少都会遇到一个场景:内存溢出。如果你没有遇到过这个场景,那就说明你是个假的程序员。哈哈,开个玩笑,平时工作过程中,我们确实会遇到这个问题。今天,我就将平时工作过程中遇到的内存溢出情况做个简单的总结,以通俗易懂的代码案例的形式直观的分享给大家。希望能够为小伙伴们带来实质性的帮助。

案例介绍

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

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

定义主类结构

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

  1. public class BlowUpJVM {   
  2. }  

栈深度溢出

  1. public static void  testStackOverFlow(){  
  2.       BlowUpJVM.testStackOverFlow();  
  3. }  

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

永久代内存溢出

  1. public static void testPergemOutOfMemory1(){  
  2.    //方法一失败  
  3.     List<String> list = new ArrayList<String>();  
  4.   
  5.    while(true){  
  6.       list.add(UUID.randomUUID().toString().intern());  
  7.    }  
  8. }  

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

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

  1. public static void testPergemOutOfMemory2(){  
  2.    try {  
  3.       while (true) {  
  4.          Enhancer enhancer = new Enhancer();  
  5.          enhancer.setSuperclass(OOM.class);  
  6.          enhancer.setUseCache(false);  
  7.          enhancer.setCallback(new MethodInterceptor() {  
  8.             @Override  
  9.             public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {  
  10.                return proxy.invokeSuper(obj, args);  
  11.             }  
  12.          });  
  13.          enhancer.create();  
  14.       }  
  15.    }  
  16.    catch (Exception e){  
  17.       e.printStackTrace();  
  18.    }  
  19. }  

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

  1. public static void testPergemOutOfMemory3(){  
  2.    while(true){  
  3.    final OOM oom = new OOM();  
  4.    Proxy.newProxyInstance(oom.getClass().getClassLoader(), oom.getClass().getInterfaces(), new InvocationHandler() {  
  5.          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
  6.             Object result = method.invoke(oom, args);  
  7.             return result;  
  8.          }  
  9.       });  
  10.    }  
  11. }  

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

本地方法栈溢出

  1. public static void testNativeMethodOutOfMemory(){  
  2.    int j = 0;  
  3.    while(true){  
  4.       Printer.println(j++);  
  5.       ExecutorService executors = Executors.newFixedThreadPool(50);  
  6.       int i=0;  
  7.       while(i++<10){  
  8.          executors.submit(new Runnable() {  
  9.             public void run() {  
  10.             }  
  11.          });  
  12.       }  
  13.    }  
  14. }  

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

JVM栈内存溢出

  1. public static void testStackOutOfMemory(){  
  2.     while (true) {    
  3.             Thread thread = new Thread(new Runnable() {    
  4.                    public void run() {  
  5.                           while(true){  
  6.                       }  
  7.                    }    
  8.             });    
  9.             thread.start();    
  10.      }    
  11. }  

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

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

堆溢出

  1. public static void testOutOfHeapMemory(){  
  2.    List<StringBuffer> list = new ArrayList<StringBuffer>();  
  3.    while(true){  
  4.       StringBuffer B = new StringBuffer();  
  5.       for(int i = 0 ; i < 10000 ; i++){  
  6.          B.append(i);  
  7.       }  
  8.       list.add(B);  
  9.    }  
  10. }  

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

本文转载自微信公众号「冰河技术」,可以通过以下二维码关注。转载本文请联系冰河技术公众号。

 

 

责任编辑:武晓燕 来源: 冰河技术
相关推荐

2020-08-06 17:16:47

抖音Tiktok美国

2021-09-01 13:46:07

GitHub Copi漏洞代码训练

2020-04-15 10:28:57

QQ腾讯更新

2021-12-26 00:13:24

Log4jLogback漏洞

2021-11-08 12:44:48

AndroidC++内存

2015-11-17 12:56:33

浪潮SC15

2021-12-07 08:27:19

RTTI运行类型

2014-11-17 09:36:45

2023-03-30 07:34:10

Linux性能数据结构

2021-01-01 09:03:44

故障HAProxy服务器

2021-08-06 11:06:35

欺诈攻击垃圾邮件广告

2009-06-15 09:47:12

Java程序内存溢出

2019-05-23 10:59:24

Java内存 C++

2018-07-27 15:04:36

比特币ETF市场

2010-10-21 14:38:07

网络融合

2014-09-02 10:19:22

IT程序员

2021-08-26 05:00:44

生产环境内存

2021-11-04 18:27:02

缓存架构Eureka

2013-12-03 10:04:04

Windows更新代号Windows 8.1

2014-09-29 14:35:57

WIFI物联网RFID
点赞
收藏

51CTO技术栈公众号