`
毕竟红尘
  • 浏览: 12769 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

误用递归引发的问题

阅读更多
  
   最近在检查模块代码的时候看到如下一段代码:

  

   //获得一个产品块
   public Vector<Product> getProductBlock() throws Exception {

                //缓存队列中已经没有数据了,则补充数据
		if (cacheQueue.isEmpty()) {

                         //补充数据
			this.supplyRecord();

                        //有可能引发问题的递归调用!!
			return this.getProductBlock();

		}

          //获得缓存队列中的第一块数据
	  return cacheQueue.remove(0);

   }


   



    this.suplyRecord()从DB中取得指定数量的记录,放到缓存队列中。客户程序通过getProductBlock()从队列中获得数据。由于处理的瓶颈在与数据库交互这边,所以通过引入这种机制,以降低了查库频率,从而提高程序的整体处理效率。

    考虑到this.suplyRecord()在取数据时,有可能获得空的数据集(也就是表中可能也没有记录了),supply方法在数据集为空时会休眠5分钟。休眠醒来通过this.getProductBlock()
再次检测数据集,如果数据集为空,则可能再次休眠。

    这样会引发什么问题呢?

    如果数据库中一直有未处理的记录,或者每隔一小段时间,就有未处理的数据入库,那么事情就没有问题,递归很快返回。但是如果一整天都没有新进来的未处理数据,那么由于是递归,那么递归的堆栈会累得非常高,消耗大量内存,到最后就可能OOM了。
   
    下面的代码可以验证这种情景:

   public class TestRecusive {

	static int count = 10;

	public static String doSomething() throws Exception {

		Thread.sleep(10000);
		if (count-- == 0) {
			return "nothing";
		}

		return doSomething();

	}

	public static void main(String[] args) throws Exception {

		doSomething();

	}



   看看,附件中,这个代码产生的堆栈。
  


 
  

  


  
  • 大小: 15.5 KB
分享到:
评论

相关推荐

    C语言教学中遇到的问题及解决办法.pdf

    宏有时会导致意外的行为,如类型错误、副作用问题或括号缺失引发的优先级问题。为避免这些问题,应谨慎使用宏,特别是在涉及到复杂表达式或需要类型安全的地方,可以考虑使用函数替代宏。 4. 输入输出函数的使用: ...

    c语言坑爹大冒险.zip

    不合理的递归可能导致栈空间耗尽,引发栈溢出。理解递归的工作原理,以及如何优化递归或避免无限递归是必要的。 9. **错误处理** C语言的标准库通常只提供简单的错误代码,而没有异常处理机制。因此,编写良好的...

    MATLAB常见错误之总结.pdf.zip

    7. **函数调用错误**:错误地使用内置函数或自定义函数参数,如函数名拼写错误、参数顺序错误或类型不匹配,都会引发错误。查阅MATLAB帮助文档或函数原型可避免此类错误。 8. **循环和递归错误**:无限循环或递归...

    core_vulnerabilities

    涉及到malloc、free等动态内存管理函数的误用,如双重释放、释放后使用等情况,同样可以引起安全问题。 #### Abo7.c - 全局变量与缓冲区溢出 全局变量如果与缓冲区位于同一内存段,缓冲区溢出可能会影响全局变量的...

    高质量C编程指南.rar

    C语言提供了直接操作内存的能力,这也意味着程序员需要对内存管理有深入的理解,以防止因误用而导致的问题。 函数的使用是C语言的一大特色。书中会介绍如何设计高效的函数,包括参数传递、局部变量与全局变量的交互...

    C语言常见面试题大全

    例如,在递归函数中如果递归基没有正确设置,可能会导致无限递归,最终耗尽所有的堆栈空间,引发堆栈溢出。此外,如果在一个函数中声明了大量局部变量,而这些变量的总大小超过了系统分配给该函数调用的堆栈空间,也...

    C-Language:雪崩

    3. **指针错误**:指针是C语言的强大工具,但也容易引发问题。未初始化的指针、空悬指针或者误用指针可能导致程序崩溃,尤其是在大型程序中,这些问题可能因为复杂的依赖关系而被隐藏,直到某个触发点才暴露出来。 ...

    浅谈js基础数据类型和引用类型,深浅拷贝问题,以及内存分配问题

    例如,如果误用浅拷贝导致意外地修改了共享对象,可能会引发难以预料的错误。同时,合理管理内存可以防止内存占用过多,提高应用的运行效率。在开发过程中,要根据需求选择适当的拷贝方式,并注意引用类型在内存中的...

    最危险的10个Linux命令,希望你牢记在心.doc

    误用此命令,如`rm -rf /`或`rm -rf *`,可能会导致系统崩溃,甚至丢失所有数据。为了避免误操作,建议在`.bashrc`文件中设置`rm`的别名,使其默认带有`-i`参数,要求用户确认删除操作。 2. `{:|:&};:`:这是创建一...

    Objective-C类方法中使用self注意事项

    - 但是,注意不要在类方法中误用`self.init`,因为这会引发无限递归,因为在类方法中`self`代表类,而非实例。 3. **静态变量与类方法**: - 在类方法中,`static`变量可以在整个类的生命周期内保持其值,适用于...

    C/C++ 宏详细解析

    虽然宏在某些情况下可以提高代码的可读性和可维护性,但过度使用或误用宏可能导致难以调试的问题。 首先,宏的定义通常以`#define`开始,比如`#define min(x,y) (x )? x : y`。宏定义的主体是被替换的文本,这里是...

    linux 的主要命令行

    这个命令用于递归删除指定路径下的所有文件及子目录。如果将根目录(`/`)作为参数传递,则会导致整个文件系统的删除。这无疑是极具破坏力的一个命令,因为一旦执行成功,将会永久性地清除系统上的所有数据和设置。...

    Ruby元编程的一些值得注意的地方

    如果误用了`method_missing`,可能会导致程序中的方法调用出现异常,甚至引发安全问题。因此,在可能的情况下,应优先考虑使用`delegate`或`define_method`来实现动态方法调用。 #### 九、捕捉定义良好的方法 在...

    深入php中var_dump方法的使用详解

    这一点很重要,因为有时候在代码中可能会出现误用未声明变量的情况,而var_dump能够帮助我们快速发现这类问题。 var_dump函数会返回变量的详细信息,并且输出到屏幕。这意味着,你不需要额外使用print_r或者其他...

    C++题目汇总终稿 701

    如果vector为空或只有一个元素,删除操作可能引发崩溃。 27. **虚函数和纯虚函数的区别**: 虚函数可以在派生类中重写,纯虚函数在基类中声明,要求派生类必须实现。 28. **C++中overload, override, overwrite的...

Global site tag (gtag.js) - Google Analytics