精华内容
下载资源
问答
  • 当初面试官让我现场手写内存溢出案例代码,我就以Java代码的方式列举了几典型的内存溢出案例。今天分享给大家,希望大家在日常工作中,尽量避免这些low水平的代码

    大家好,我是冰河~~

    作为程序员,多多少少都会遇到一些内存溢出的场景,如果你还没遇到,说明你工作的年限可能比较短,或者你根本就是个假程序员!哈哈,开个玩笑。

    当初面试官让我现场手写内存溢出案例代码,我就以Java代码的方式列举了几个典型的内存溢出案例。今天分享给大家,希望大家在日常工作中,尽量避免写这些low水平的代码。

    小伙伴们点赞,收藏,评论,走起呀

    我们先来看看今天要介绍哪些内存溢出案例,冰河这里总结了一张图,如下所示。

    说干就干,咱们开始吧!!

    定义主类结构

    首先,我们创建一个名称为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对象,堆满了就直接溢出了。

    测试案例完整代码

    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()); 
           } 
        } 
        
        //永久代溢出
        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(); 
           } 
        } 
        
        //不会引起永久代溢出
        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; 
                 } 
              }); 
           } 
        } 
        
        //本地方法栈溢出
        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() { 
                    } 
                 }); 
              } 
           } 
        } 
        
        //JVM内存溢出
        public static void testStackOutOfMemory(){ 
            while (true) {   
                    Thread thread = new Thread(new Runnable() {   
                           public void run() { 
                                  while(true){ 
                              } 
                           }   
                    });   
                    thread.start();   
             }   
        } 
        
        //堆溢出
        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); 
           } 
        } 
    } 
    

    写在最后

    如果你想进大厂,想升职加薪,或者对自己现有的工作比较迷茫,都可以私信我交流,希望我的一些经历能够帮助到大家~~

    推荐阅读:

    最后,附上并发编程需要掌握的核心技能知识图,祝大家在学习并发编程时,少走弯路。

    在这里插入图片描述

    好了,今天就到这儿吧,小伙伴们点赞、收藏、评论,一键三连走起呀,我是冰河,我们下期见~~

    展开全文
  • symfony2中自己一个事件监听案例

    千次阅读 2016-01-12 19:21:26
    事件监听的原因:项目中所有的控制器里面的操作,

    写这个事件监听的原因:项目中所有的控制器里面的操作,都必须是登录以及必须有权限。

    1.创建一个监听类


    2.将类注册成服务

    app/config/services.yml


    3.在监听类里面写东西

    <?php
    
    namespace AppBundle\EventListener;
    
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\HttpFoundation\JsonResponse;
    use Symfony\Component\HttpKernel\Event\GetResponseEvent;
    
    use Material\Exception\NoAuthorityException;
    use Material\Exception\BaseException;
    
    class AuthListener
    {
    
        public function onKernelRequest(GetResponseEvent $event)
        {
            return;
            $request = $event->getRequest();
            $targetUser = $request->getSession()->get('targetUser');
            if (empty($targetUser)) {
                throw new NoAuthorityException('未登陆');
            }
            if (!$targetUser->isMember()) {
                throw new NoAuthorityException('不是会员,没有权限');
            }
        }
    
    }

    未完待续

    展开全文
  • 平常使用过程中我们对于enum很少使用,实际上枚举有很多用处,下面是一个关于用枚举代替if-else的一个案例。可以让你的代码更具可扩展性,减少加班改需求的可能。 下面是一个关于加减乘除四则运算的设计 一般的写法...

    首先要感谢大佬 杭州-java-牧头的倾囊教授

    大佬的博客地址:http://googlevip8.com/
    平常使用过程中我们对于enum很少使用,实际上枚举有很多用处,下面是一个关于用枚举代替if-else的一个案例。可以让你的代码更具可扩展性,减少加班改需求的可能。

    下面是一个关于加减乘除四则运算的设计

    一般的写法是if-else

    If-else方式

    public class IfElse的方式 {
    
        public static void main(String[] args) {
            int leftNum = 1;
            int rightNum = 2;
            int result = 0;
            String start = "*";
    
            if (start != null) {
                if (start.equals("+")) {
                    result = leftNum + rightNum;
                } else if (start.equals("-")) {
                    result = leftNum - rightNum;
                } else if (start.equals("*")) {
                    result = leftNum * rightNum;
                } else if (start.equals("/")) {
                    result = leftNum / rightNum;
                }else {
                    throw new IllegalArgumentException("不支持该运算");
                }
            }else {
                throw new NullPointerException(" start 运算符不能为空");
            }
        }
    }
    

    策略模式+工厂模式

    import java.util.HashMap;
    import java.util.Map;
    
    public class 加减乘除策略模式加工厂模式Map {
        private final static Map<String, ParentStart> map;
    
        static {
            map = new HashMap<>();
            map.put("+", new Plus());
            map.put("-", new Subtract());
            map.put("*", new Multiply());
            map.put("/", new Divide());
            map.put(null, new MyException());
        }
    
        public static void main(String[] args) {
            int leftNum = 1;
            int rightNum = 2;
            int result = 0;
            String start = "*";
    
            result = map.getOrDefault(start, new MyException()).run(leftNum, rightNum);
            System.out.println(result);
        }
    }
    
    /**
     * 策略模式 中的父级
     */
    abstract class ParentStart {
        /**
         *
         * @param leftNum 运算符左边的操作数
         * @param rightNum 运算符右边的操作数
         * @return 计算后的结果
         */
        int run(int leftNum, int rightNum);
    }
    
    /**
     * 策略模式中的加的方法
     */
    class Plus extends ParentStart {
        @Override
        int run(int leftNum, int rightNum) {
            return leftNum + rightNum;
        }
    }
    
    /**
     * 策略模式中的减的方法
     */
    class Subtract extends ParentStart {
        @Override
        int run(int leftNum, int rightNum) {
            return leftNum - rightNum;
        }
    }
    
    /**
     * 策略模式中的乘的方法
     */
    class Multiply extends ParentStart {
        @Override
        int run(int leftNum, int rightNum) {
            return leftNum * rightNum;
        }
    }
    
    /**
     * 策略模式中的除的方法
     */
    class Divide extends ParentStart {
        @Override
        int run(int leftNum, int rightNum) {
            return leftNum / rightNum;
        }
    }
    
    /**
     * 策略模式中的非法操作
     */
    class MyException extends ParentStart {
        @Override
        int run(int leftNum, int rightNum) {
            throw new IllegalArgumentException("运算符不存在");
        }
    }
    

    枚举方式+策略模式(推荐使用)

    import java.util.HashMap;
    import java.util.Map;
    
    public class Enmu枚举方式 {
        private final static Map<String, String> map;
    
        static {
            map = new HashMap<>();
            map.put("+", "ADD");
            map.put("-", "SUBTRACT");
            map.put("*", "MULTIPLY");
            map.put("/", "DIVIDION");
        }
    
        public static void main(String[] args) {
            int leftNum = 1;
            int rightNum = 2;
            int result = 0;
            String option= "*"; // 运算操作
    
            String strategy = map.getOrDefault(option, "EXCEPTION");// 得到策略
            result = CalculateEnum .valueOf(strategy).calculate(leftNum, rightNum);// 根据策略调用得到对应枚举,调用对应的方法得到计算的结果
    
            System.out.println(result); // 打印计算后的结果
        }
    }
    
    enum CalculateEnum {
    
        ADD {
            @Override
            public int calculate(int leftNum, int rightNum) {
                return leftNum + rightNum;
            }
        },
        SUBTRACT {
            @Override
            public int calculate(int leftNum, int rightNum) {
                return leftNum - rightNum;
            }
        },
        MULTIPLY {
            @Override
            public int calculate(int leftNum, int rightNum) {
                return leftNum * rightNum;
            }
        },
        DIVIDION {
            @Override
            public int calculate(int leftNum, int rightNum) {
                return leftNum / rightNum;
            }
        },
        EXCEPTION {
            @Override
            public int calculate(int leftNum, int rightNum) {
                throw new IllegalArgumentException("运算操作不支持");
            }
        };
    
    	/**
    	 * 将操作数 leftNum,rightNum 运算得到新值
    	 * return 计算后的结果值
    	 */
        int calculate(int leftNum, int rightNum);
    
    }
    

    各种方式的优缺点

    从代码量来说if-else的代码量是更少,但是if-else的代码会导致业务逻辑不具备可变性。
    需求改变时会导致直接修改源代码。

    if-else方式:如果添加一个求余运算会导致直接修改if-else分支添加一个分支。如果需求多时会导致很多分支,代码看起来非常难受。

    策略+工厂方式:通过子类重写父类抽象方法可以扩展需求,有多少个功能就需要多少个子类。这种方式缺点就是子类太多,不方便管理

    枚举 + 策略:通过修改枚举,增加策略,实际和第二种差不多,但是比第二种方式更具灵活性。

    第二种和第三种方式都起到了简化的作用,原先需要用if-else写一长串的代码,现在我们通过枚举或者工厂,简化成几行代码,主要是看起来很清晰(相当于起到了封装的作用)。

    文章末尾,再次感谢大佬 杭州-java-牧头 的不吝赐教
    展开全文
  • 案例1:创建一个新文件,写入5句 :hello,Go语言 package main import ( "fmt" "os" "bufio" ) func main() { //创建一个新文件,写入内容 5句 hello,Go语言 filePath := "c:/amyfile/abc.txt" file, err :=...

    os包下面有OpenFile函数:在这里插入图片描述

    案例1:创建一个新文件,写入5句 :hello,Go语言

    package main
    
    import (
    	"fmt"
    	"os"
    	"bufio"
    )
    
    func main() {
    	//创建一个新文件,写入内容 5句 hello,Go语言
    	filePath := "c:/amyfile/abc.txt"
    	file, err := os.OpenFile(filePath, os.O_WRONLY | os.O_CREATE, 0666)
    	if err != nil{
    		fmt.Println("open file err",err)
    	}
    	//及时关闭file句柄
    	defer file.Close()
    
    	//写入文件时,使用带缓存的 *Writer
    	write := bufio.NewWriter(file)
    	for i := 0; i < 5; i++ {
    		write.WriteString("hello,Go语言 \n")
    	}
    	//Flush将缓存的文件真正写入到文件中
    	write.Flush()
    }
    

    执行之后,可以看出文件已被写入:
    在这里插入图片描述

    案例2:打开一个存在的文件,在原来的内容追加内容:ABC!!

    package main
    
    import (
    	"fmt"
    	"os"
    	"bufio"
    )
    
    func main() {
    	//创建一个新文件,写入内容 5句 hello,Go语言
    	filePath := "c:/amyfile/abc.txt"
    	file, err := os.OpenFile(filePath, os.O_WRONLY | os.O_APPEND, 0666)
    	if err != nil{
    		fmt.Println("open file err",err)
    	}
    	//及时关闭file句柄
    	defer file.Close()
    
    	//写入文件时,使用带缓存的 *Writer
    	write := bufio.NewWriter(file)
    	for i := 0; i < 5; i++ {
    		write.WriteString("ABC! \r\n")
    	}
    	//Flush将缓存的文件真正写入到文件中
    	write.Flush()
    }
    

    执行,发现内容追加成功:
    在这里插入图片描述

    案例3:打开一个存在的文件,将原来的内容读出来,显示在终端,并且追加5句:hello,北京。

    package main
    
    import (
    	"fmt"
    	"os"
    	"bufio"
    	"io"
    )
    
    func main() {
    	//创建一个新文件,写入内容 5句 hello,Go语言
    	filePath := "c:/amyfile/abc.txt"
    	file, err := os.OpenFile(filePath, os.O_RDWR | os.O_APPEND, 0666)
    	if err != nil{
    		fmt.Println("open file err",err)
    	}
    	//及时关闭file句柄
    	defer file.Close()
    
    	//读原来文件的内容,并且显示在终端
    	reader := bufio.NewReader(file)
    	for {
    		str, err := reader.ReadString('\n')
    		if err == io.EOF {
    			break
    		}
    		fmt.Print(str)
    	}
    
    	//写入文件时,使用带缓存的 *Writer
    	write := bufio.NewWriter(file)
    	for i := 0; i < 5; i++ {
    		write.WriteString("hello,北京。 \r\n")
    	}
    	//Flush将缓存的文件真正写入到文件中
    	write.Flush()
    }
    

    执行,原来的文件在控制台读取成功,并且在文件中追加成功:
    在这里插入图片描述

    案例4:编写一个程序,将一个文件的内容复制到另外一个文件(注:这两个文件都已存在)

    package main
    
    import (
    	"fmt"
    	"io/ioutil"
    )
    
    func main() {
    	//创建一个新文件,写入内容 5句 hello,Go语言
    	file1Path := "c:/amyfile/abc.txt"
    	file2Path := "c:/amyfile/defer.txt"
    	data, err := ioutil.ReadFile(file1Path)
    	if err != nil{
    		fmt.Printf("open file err=%v\n",err)
    		return
    	}
    	err = ioutil.WriteFile(file2Path, data,0666)
    
    	if err != nil{
    		fmt.Printf("open file err=%v\n",err)
    	}
    }
    

    执行,发现内容复制成功:
    在这里插入图片描述

    展开全文
  • 我们前面讲了几篇关于类的知识点,为了让大家更好的掌握类的概念,并灵活的运用这些知识,我一个有趣又好玩的弹球的游戏,一来可以把类的知识融会一下,二来加深对Python的兴趣.你会发现哎呀Python小游戏还是蛮...
  • 4 Three.js一个案例详解

    千次阅读 2017-07-04 12:02:10
    之前根绝官网书写了两个简单的案例,今天开始一个教程书里面的案例案例查看地址:http://www.wjceo.com/blog/threejs/2018-02-09/6.html(1)创建了渲染器,并传值对象antialias设置为true,告诉Three.js要...
  • selenium操作ie的浏览器是无法操作的,需要通过driver才可以操作,google官方解释为:InternetExplorerDriver 是一个独立的服务器,实现 WebDriver 的有线协议。此驱动程序已经过测试与 IE 6、 7、 8、 9 和 XP、 ...
  • 宋宝华:关于Ftrace的一个完整案例

    万次阅读 2018-01-24 23:49:39
    更多精华文章或者加入技术交流群请扫描下方二维码关注Linux阅码场 Ftrace简介 Ftrace是Linux进行代码级实践分析最有效的...写一个proc模块,包含一个proc的读和的入口。test_proc_show()故意调用了一个kill_...
  • onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth)
  • spring boot实战(第一篇)第一个案例

    万次阅读 多人点赞 2015-08-25 23:29:28
    spring boot实战(第一篇)第一个案例前言在前面的话一直想将spring boot相关内容一个系列的博客,今天终于有时间开始了第一篇文章 以后有时间就会继续下去。 spring boot 博客内容规划 spring boot 基本用法 ...
  • Mycat生产实践---Mycat读写分离案例

    千次阅读 2017-03-30 16:44:42
    大多数读写分离的案例是同时支持高可用性的,即Mycat+MySQL主从复制的集群,并开启Mycat的读写分离功能,这种场景需求下,Mycat是最为简单并且功能最为丰富的类Proxy,正常情况下,配置文件也最为简单,不用每表...
  • TensorFlow使用的一个案例

    万次阅读 2017-03-26 16:56:09
    TensorFlow使用的一个案例上一篇博客我们已经安装了TensorFlow,有很多人可能会对机器学习感到害怕,但其实有好多原理我们现在不需要懂,我们先搞清楚TensorFlow有什么作用就行,那么下面我通过一个小的案例来说明...
  • Jmeter 是款使用Java开发的,开源免费的,测试工具, 主要用来做功能测试和性能测试(压力测试/负载测试). 而且用Jmeter 来测试 Restful API, 非常好用。   如何学好Jmeter 如果你用Jmeter去对Web进行功能...
  • 一元谓词案例与二元谓词案例

    千次阅读 2017-11-26 18:24:22
    一元谓词案例与二元谓词案例
  • 一个多态经典案例

    千次阅读 2017-12-25 23:16:22
    Java中绑定的所有方法都采用后期绑定技术,除非一个方法已被声明成final。这意味着我们通常不必决定是否应进行后期绑定——它是自动发生的 //A相当于爷爷类,B相当于父亲类,B继承A //C,D相当于儿子类,都继承...
  • 案例要求: 判断某个用户名是否存在,若存在,则把密码改为”888888“,若不存在,就... ... 使用map[string]map[string]string 的map类型; 编写一个函数modifyUser(users map[string]map[string]string,name strin...
  • Cocos Creator第一个案例

    千次阅读 2018-10-06 21:00:18
    代码采用键值对形式,将脚本添加给精灵之后,他会变成一个我们自己定义的组建,可以设置值大小。。。 这些都挺容易明白,麻烦的是方法。。。。 setJumpAction: function () { // 跳跃上升 var jumpUp = cc....
  • 一个完整的ajax简单案例

    万次阅读 多人点赞 2017-04-23 15:35:33
    ajax简单完整案例
  • 使用Spring AOP实现MySQL数据库读写分离案例分析

    万次阅读 多人点赞 2016-12-29 19:15:43
    一、前言分布式环境下数据库的读写分离策略是解决数据库读写性能瓶颈的一个关键解决方案,更是最大限度了提高了应用中读取 (Read)数据的速度和并发量。在进行数据库读写分离的时候,我们首先要进行数据库的主从...
  • 刚做完一次网络切换支持,得空一篇,其实今儿取了巧,这篇文章是之前过的,碰巧又是这次“执行计划异常变更”案例涉及的一个知识点,所以再次翻出来。之前的几篇文章: 《一个执行计划异常变更的案例 - 前传》 ...
  • 我们知道List的实现类ArrayList,LinkedList都是非线程安全的,Vector类通过用synchronized修饰方法保证了List的多线程非安全问题,但是有缺点:读写同步,效率低下。于是就出现了CopyOnWriteArrayList,它通过...
  • 关于沟通问题的一个案例

    千次阅读 2012-05-04 10:55:33
    我们需要测试一个安装包,安装包中包含了数据库升级脚本,这是测试的一个重点。我们以前能访问客户的一台服务器,并且在5.2号对数据库进行了备份,但是在5.3号手动对数据库进行了一点修改,这些修改是不包含的备份中...
  • 数据字典的一个简单案例

    万次阅读 2015-03-03 18:15:57
    系统开发的论文中提到数据字典,这怎么?与数据库的逻辑设计、物理设计有什么区别?老师说数据字典应该从数据项、数据结构、数据存储、数据流和数据处理几方面来?有人能给列子吗?逻辑设计如下:某表1(菜...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 480,512
精华内容 192,204
关键字:

如何写一个案例