堆栈

jvm栈和堆详解

不想你离开。 提交于 2020-01-15 06:32:55
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的 一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配 。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。 堆内存用于存放由new创建的对象和数组 。在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在堆内存中的首地址,在栈中的这个特殊的变量就变成了数组或者对象的引用变量,以后就可以在程序中使用栈内存中的引用变量来访问堆中的数组或者对象,引用变量相当于为数组或者对象起的一个别名,或者代号。 引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放。而数组&对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放, 数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因, 实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针! java中内存分配策略及堆和栈的比较   1 内存分配策略  

JS 之 引擎运行原理

一个人想着一个人 提交于 2020-01-14 11:06:13
今天跟大家分享下JS 之 引擎运行原理的知识。 1 一些名词 JS引擎 — 一个读取代码并运行的引擎,没有单一的“JS引擎”;,每个浏览器都有自己的引擎,如谷歌有V。 作用域 — 可以从中访问变量的“区域”。 词法作用域— 在词法阶段的作用域,换句话说,词法作用域是由你在写代码时将变量和块作用域写在哪里来决定的,因此当词法分析器处理代码时会保持作用域不变。 块作用域 — 由花括号{}创建的范围 作用域链 — 函数可以上升到它的外部环境(词法上)来搜索一个变量,它可以一直向上查找,直到它到达全局作用域。 同步 — 一次执行一件事, “同步”引擎一次只执行一行,JavaScript是同步的。 异步 — 同时做多个事,JS通过浏览器API模拟异步行为 事件循环(Event Loop) - 浏览器API完成函数调用的过程,将回调函数推送到回调队列(callback queue),然后当堆栈为空时,它将回调函数推送到调用堆栈。 堆栈 —一种数据结构,只能将元素推入并弹出顶部元素。 想想堆叠一个字形的塔楼; 你不能删除中间块,后进先出。 堆 — 变量存储在内存中。 调用堆栈 — 函数调用的队列,它实现了堆栈数据类型,这意味着一次可以运行一个函数。调用函数将其推入堆栈并从函数返回将其弹出堆栈。 执行上下文 — 当函数放入到调用堆栈时由JS创建的环境。 闭包 — 当在另一个函数内创建一个函数时,它

在一个数组中实现两个堆栈 (20分)

自古美人都是妖i 提交于 2020-01-13 20:54:25
在一个数组中实现两个堆栈 (20分) 本题要求在一个数组中实现两个堆栈。 函数接口定义: Stack CreateStack ( int MaxSize ) ; bool Push ( Stack S , ElementType X , int Tag ) ; ElementType Pop ( Stack S , int Tag ) ; 其中Tag是堆栈编号,取1或2;MaxSize堆栈数组的规模;Stack结构定义如下: typedef int Position ; struct SNode { ElementType * Data ; Position Top1 , Top2 ; int MaxSize ; } ; typedef struct SNode * Stack ; 注意:如果堆栈已满,Push函数必须输出“Stack Full”并且返回false;如果某堆栈是空的,则Pop函数必须输出“Stack Tag Empty”(其中Tag是该堆栈的编号),并且返回ERROR。 裁判测试程序样例: # include <stdio.h> # include <stdlib.h> # define ERROR 1e8 typedef int ElementType ; typedef enum { push , pop , end } Operation ; typedef

Java 多线程间的通讯

瘦欲@ 提交于 2020-01-13 20:32:26
问题 在前一小节,介绍了在多线程编程中使用同步机制的重要性,并学会了如何实现同步的方法来正确地访问共享资源。这些线程之间的关系是平等的,彼此之间并不存在任何依赖,它们各自竞争CPU资源,互不相让,并且还无条件地阻止其他线程对共享资源的异步访问。然而,也有很多现实问题要求不仅要同步的访问同一共享资源,而且线程间还彼此牵制,通过相互通信来向前推进。那么,多个线程之间是如何进行通信的呢? 解决思路 在现实应用中,很多时候都需要让多个线程按照一定的次序来访问共享资源,例如,经典的生产者和消费者问题。这类问题描述了这样一种情况,假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中的产品取走消费。如果仓库中没有产品,则生产者可以将产品放入仓库,否则停止生产并等待,直到仓库中的产品被消费者取走为止。如果仓库中放有产品,则消费者可以将产品取走消费,否则停止消费并等待,直到仓库中再次放入产品为止。显然,这是一个同步问题,生产者和消费者共享同一资源,并且,生产者和消费者之间彼此依赖,互为条件向前推进。但是,该如何编写程序来解决这个问题呢? 传统的思路是利用循环检测的方式来实现,这种方式通过重复检查某一个特定条件是否成立来决定线程的推进顺序。比如,一旦生产者生产结束,它就继续利用循环检测来判断仓库中的产品是否被消费者消费

uC/OS任务创建

眉间皱痕 提交于 2020-01-13 13:18:15
1.任务的定义 1)定义任务堆栈 1 #define TASK1_STK_SIZE 128 2 #define TASK2_STK_SIZE 128 3 4 static CPU_STK Task1Stk[TASK1_STK_SIZE]; 5 static CPU_STK Task2Stk[TASK2_STK_SIZE]; 2)定义任务函数 3)定义任务控制块 任务控制块是一种数据类型,包含着任务的所有信息(任务堆栈,名字,优先级,链表指针等),任务的执行是通过系统的调度,系统对任务的操作则是通过任务控制块来实现 4)定义任务函数 2.系统初始化 系统初始化一般是在硬件初始化完成之后进行 3.启动系统 1 void OSStart (OS_ERR *p_err) 2 { 3 if ( OSRunning == OS_STATE_OS_STOPPED ) { 4 /* 手动配置任务 1 先运行 */ 5 OSTCBHighRdyPtr = OSRdyList[0].HeadPtr; 6 7 /* 启动任务切换*/ 8 OSStartHighRdy(); 9 10 /* 不会运行到这里,运行到这里表示发生了致命的错误 */ 11 *p_err = OS_ERR_FATAL_RETURN; 12 } else { 13 *p_err = OS_STATE_OS_RUNNING; 14 }

log4j2之简化封装,告别静态成员变量

心已入冬 提交于 2020-01-12 00:28:45
注 本文是使用 slf4j + log4j2 示例,由于 slf4j 只是一个统一接口包,log4j / log4j2 / logback 等都是有其实现类,所以本文中是以 slf4j 为例。若有朋友坚持不使用 slf4j ,则将代码中 slf4j 相关的都做对应更改即可,并不麻烦。 序 一般情况下,每当我们使用 slf4j 等log组件时,都是在需要记载日志的类中,创建一个静态的 Logger 成员变量,然后调用 debug,info,error 等方法。这就意味着我们每一个要记载日志的类,都需要先定义一个静态的成员变量,这样才打印出正确的前缀(带有类名称) 一、现状 我们以码云中几个热门的java项目为例(下面的代码片段都是 star 超过 500+ 的项目) public class DepartController { private static final Logger logger = Logger.getLogger(DepartController.class); ... method() { logger.info("some things!"); } } @Controller public class LoginController extends BaseController { private static final Logger LOGGER =

vs2010设置堆栈大小

守給你的承諾、 提交于 2020-01-11 15:29:12
在解释原因前我们先看一下一个由C/C++编译的程序占用的内存分为几个部分: 1、 栈区(stack segment) :由编译器自动分配释放,存放函数的参数的值,局部变量的值等。在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。 2、 堆区(heap segment) : 一般由程序员分配释放,若程序员不释放,程序结束时可能由系统回收 。它与数据结构中的堆是两回事。堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。 3、 全局区(静态区)(data segment) :全局变量和静态变量的存储区域是在一起的,程序结束后由系统释放。数据区的大小由系统限定,一般很大。 4、文字常量区:常量字符串就是放在这里的, 程序结束后由系统释放。 5、程序代码区:存放函数体的二进制代码。 综上所述,局部变量空间是很小的,我们开一个a[1000000]就会导致栈溢出

进程中堆栈向下增长的原因

自闭症网瘾萝莉.ら 提交于 2020-01-11 02:54:23
http://www.cnblogs.com/Quincy/archive/2012/03/27/2418835.html 我们都知道X86系统进程中堆栈都向下增长的,那为什么是向下增长呢? “这个问题与虚拟地址空间的分配规则有关,每一个可执行C程序,从低地址到高地址依次是:text,data,bss,堆,栈,环境参数变量;其中堆和栈之间有很大的地址空间空闲着,在需要分配空间的时候,堆向上涨,栈往下涨。” 这样设计可以使得堆和栈能够充分利用空闲的地址空间。 如果栈向上涨的话,我们就必须得指定栈和堆的一个严格分界线,但这个分界线怎么确定呢?平均分?但是有的程序使用的堆空间比较多,而有的程序使用的栈空间比较多。所以就可能出现这种情况:一个程序因为栈溢出而崩溃的时候,其实它还有大量闲置的堆空间呢,但是我们却无法使用这些闲置的堆空间。所以呢,最好的办法就是让堆和栈一个向上涨,一个向下涨,这样它们就可以最大程度地共用这块剩余的地址空间,达到利用率的最大化!! 呵呵,其实当你明白这个原理的时候,你也会不由地惊叹当时设计计算机的那些科学家惊人的聪明和智慧!! http://www.cnblogs.com/encode/p/3343499.html 51的栈是向高地址增长, INTEL 的 8031 、 8032 、 8048 、 8051 系列使用向高地址增长的堆栈;但同样是 INTEL

DS堆栈--括号匹配

馋奶兔 提交于 2020-01-10 20:45:44
题目描述 处理表达式过程中需要对括号匹配进行检验,括号匹配包括三种:“(”和“)”,“[”和“]”,“{”和“}”。例如表达式中包含括号如下: ( ) [ ( ) ( [ ] ) ] { } 1 2 3 4 5 6 7 8 9 10 11 12 从上例可以看出第1和第2个括号匹配,第3和第10个括号匹配,4和5匹配,6和9匹配,7和8匹配,11和12匹配。从中可以看到括号嵌套的的情况是比较复杂的,使用堆栈可以很方便的处理这种括号匹配检验,可以遵循以下规则: 1、 当接收第1个左括号,表示新的一组匹配检查开始;随后如果连续接收到左括号,则不断进堆栈。 2、 当接受第1个右括号,则和最新进栈的左括号进行匹配,表示嵌套中1组括号已经匹配消除 3、 若到最后,括号不能完全匹配,则说明输入的表达式有错 建议使用C++自带的stack对象来实现 stack类使用的参考代码 n包含头文件<stack> : #include <stack> n创建一个堆栈对象s(注意stack是模板类):stack <char> s; //堆栈的数据类型是字符型 n把一个字符ct压入堆栈: s.push(ct); n把栈顶元素弹出:s.pop(); n获取栈顶元素,放入变量c2: c2 = s.top(); n判断堆栈是否空: s.empty(),如果为空则函数返回true,如果不空则返回false 输入

SYS/BIOS知识整理汇总

泪湿孤枕 提交于 2020-01-10 17:31:14
本文主要整理BIOS相关组件的执行原理及使用,这里主要包括了硬件中断Hwi模块、软件中断Swi模块、时钟Clock模块、任务Tsk模块、信号量Sem模块。 1.SYS/BIOS概述 SYS/BIOS是一个可扩展的实时内核(或者说是操作系统),其提供了许多模块化的APIs(应用程序接口),支持抢占式多线程,硬件抽象,实时分析和配置工具,其设计目的是为了最大限度地减少对内存和CPU的要求。其拥有很多实时嵌入式操作系统的功能,如任务的调度,任务间的同步和通信,内存管理,实时时钟管理,中断服务管理等。有了它,用户可以编写复杂的多线程程序,并且会占用更少的CPU和内存资源。 SYS/BIOS的早期版本是DSP/BIOS,更名的原因,是因为SYS/BIOS不仅可以用于DSP,而且也可以嵌入到ARM等其他Soc中去。SYS/BIOS是一个可用于实时调度、同步,主机和目标机通信,以及实时分析系统上的一个可裁减实时内核,它提供了抢占式的多任务调度,对硬件的及时反应,实时分析和配置工具等。同时也提供标准的API接口,易于使用。它是TI的eXpressDSP实时软件技术的的一个关键部分。 2.开发环境 CCS支持SYS/BIOS的开发,用户单独下载安装bios组件即可运行,能够大大方便用户编写多任务应用程序。 3.SYS/BIOS相比裸机的优点 适用于复杂系统,在需要同时处理多个事件时SYS