共计 1326 个字符,预计需要花费 4 分钟才能阅读完成。
- 背景: 以前拿着本人的简历去面试的时候, 被问过堆栈的问题, 就查了下材料, 只知其一; 不知其二, 背了一下. 当初作为一面面试官, 上头安顿面他人, 并且领导说二面问到了堆栈相干的, 于是就在昨天夜里, 月黑风高, 灵机一动, 拆解了一下 栈
- 一些系统的知识点: 办法栈, 线程栈, 后进先出,StackOverFlow 栈溢出
- 拆解 后进先出, 网上查了栈这个汉字的本意, 最最原始的意思是 ” 现代用竹木条横排编成车箱的轻便车子 ”, 作为黄淮地区农村人, 大略就是相似 ” 平车 ” 一样的货色了. 简略了解就是 那块平板就是栈, 加上轮子就是车. 平板大略是 两根竹子, 每根都是一头绑住, 而后劈开直径, 拿竹片塞到劈开的缝隙, 塞到差不多长度后就再略微绑一下. 那么要取其中的竹片, 只能从 “ 略微绑一下 ” 的这头一个一个取, 也就是后进先出了. 牵强了点, 就酱.
- 拆解 办法栈, 线程栈, 依照下面的解释, 办法栈就是一片竹片, 外面放着办法用到的内存, 办法用到的内存根本就是根本数据的值 + 对象援用的地址. 所以才不须要多大空间. 一个个办法的调用, 就让调用链有了深度, 就像 一个个竹片塞到竹缝隙里, 所以, 就能了解到 线程栈和办法栈是一对多的关系.
- 拆解 StackOverFlow, 首先内存是有大小限度的, 堆内存也好占内存也罢, 操作系统给 jvm 过程一个内存大小,jvm 给线程栈设置一个最大的内存大小, 栈内存不够就有了 StackOverFlow, 也就是缝隙塞满了竹片, 下一个竹片就像给水杯倒水一样 ” 溢出了 ”.
- 再拆解 StackOverFlow, 依据 5, 根本的概念理解了. 那么, 是什么导致栈溢出呢, 查资料会发现, 递归深度过深灰导致栈溢出. 那么整体的逻辑就是, 某个线程执行到递归时, 第一次执行, 把以后执行的递归办法里的变量做一个快照, 放到一个栈帧 (竹片) 里, 压入栈, 而后再次调用该办法(递归了开始), 又生成一个栈帧, 再递归, 就把上一个栈帧压入栈, 而后生成一个新的栈帧. 循环上来, 当最初一次调用该办法, 并返回后, 该办法对应的栈帧就从 栈顶 去除并开释. 而后顺次开释前面的栈帧. 那么, 如果递归次数过多, 就会导致超过配置的线程栈内存大小, 就会 StackOverFlow 了.
- 思考 StackOverFlow, 大学时, 做过一个题目, 大略是已知入栈的程序是 12345, 下列哪个不是可能得出栈程序. 这个题目的精华就是办法栈帧 在 线程的栈上的进出规定了. 比方先入 123, 此时能够取出 3, 也能够再取出 2 和 1, 然而不能间接取出 2. 而 12345 这些数字, 就是所谓的 ” 栈帧 ” 了, 也是办法栈.
- 就这? 就这. 有的文章说, 办法要小, 也就是代码行数少, 一个大办法, 最好是一个在这个办法管制整体流程, 而后用小办法做各个细节逻辑. 也就是大工作拆成小工作. 之前始终不了解为啥, 有的人说是为了可读性, 但我感觉不全是, 对熟悉业务逻辑的人来说, 可读性更好了, 因为你晓得小办法里干了啥. 但对不熟悉业务的人来说, 比方交接不谨严的团队, 相熟代码就是在办法中跳来跳去, 还不如一个大办法可读性好. 但如果从栈内存优化方面来思考, 小办法就是牵强附会的存在了. 假如一个大办法占用 1m 内存, 假如设置的占内存是 900k, 那么间接运行这个大办法会栈溢出. 把大办法拆小, 就能拿立即回收掉完结的小办法的栈内存, 而后反复利用, 就不会栈溢出.
正文完