为什么我输入如下代码,为什么代码对了但是程序无法运行什么也不会输出?

1.程序的翻译环境和执行环境

在ANSI C的任何一种实现中,存在两个不同的环境

  • 第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令,也就是从,c文件到.exe文件;
  • 第2种是执行环境,它用于实际执行代码;

翻译环境是由编译器提供的,而执行环境是由操作系统提供的。

如MSVC,DEV C++,Codeblocks这些编译软件都是集成开发环境,也就是集成了编辑,编译,链接和调试等功能。

2.1程序翻译环境下的编译和链接

从源文件到可执行程序可以分为编译和链接两步,在编译阶段源文件变成了目标文件,在链接阶段目标文件变成了可执行程序。

组成程序的每个源文件通过编译过程分别转化成目标文件;

每个目标文件由链接器捆绑在一起,形成一个单一而完整的可执行程序;

链接器同时也会引入标准C函数库中任何被该程序所用到的函数,而且链接器也可以搜索程序员个人的程序库,将其需要的函数也链接到程序中。

2.2深入编译和链接过程

编译本身可以分为预编译(预处理),编译和汇编。

预编译:在预编译阶段会将#include引用的头文件给输入到文件里面,进行#define定义的标识符的替换,以及将注释给删除,因为注释是给程序员看的,不是给电脑看的;

编译:在这个过程中会将C语言代码翻译成汇编代码,编译器会对代码进行词法分析,语法分析,语义分析,符号汇总;

汇编:会把在编译阶段形成的汇编代码翻译成二进制的指令,并将汇总的符号形成一个符号表;

在编译完成之后,就会开始链接,链接过程会合成段表,也就是将目标文件捆绑在一起,以及将符号表合并并进行重定位,最后生成可执行程序。

  • 1.程序必须载入内存中。在有操作系统的环境中,一般这个过程由操作系统完成,在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
  • 2.程序开始执行,并调用main函数。
  • 3.开始执行程序代码,这个时候程序将使用一个运行时堆栈,存储函数的局部变量和返回地址,程序同时也可以使用静态内存,存储于静态内存中的变量在程序的整个执行过程一种保留它们的值。
  • 4.终止程序。正常终止main函数,也有可能是意外终止。

预定义符号都是语言内置的

// 如果定义的 stuff过长,可以分成几行写,除了最后一行外,每行的后面都加一个反斜杠(续行符)。

在define定义标识符的时候,不要在最后加上;

如下面这种情况,会出现语法错误

#define机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏或宏定义

其中的parament-list是一个由逗号隔开的符号表,它们可能出现在stuff中

参数列表的左括号必须与name紧贴,如果两者之间存在空格,参数列表就会被解释为stuff的一部分,语法就是这么规定的。

比如用宏实现一个数的平方:

解释:宏先是接受一个参数,SQRARE(n)中的n就变成了6,其后宏的内容也就由n * n变成了6 * 6,再将6 * 6替换到程序中使用宏的位置。

但是,这个宏这么写存在一个问题,如下代码:

看上去似乎最后的结果是16,然而实际上参数n会被替换成1 + 3,这样最终替换的内容是1 + 3 * 1 + 3,这条表达式最终的结果是7.

所以需要在n的左右两边加上一对括号,如下:

 看上去最终结果似乎是30,然而替换后语句实际上是

所以为了保证获得想要的结果,宏定义表达式两边还需要加上一对括号

所以用于对数值表达式进行求值的宏定义都应该用这种方式加上括号,避免在使用宏时由于参数中
的操作符或邻近操作符之间产生不可预料的相互作用。 

在程序中扩展#define定义符号和宏时,需要涉及几个步骤

  • 1.在调用宏时,首先对宏括号中的参数进行检查,看看是否包含由#define定义的符号,如果有,这些符号首先被替换。
  • 2.替换文本后,文本被插入到程序中原来文本的位置,对于宏,参数名被对应的值所替换。
  • 3.最后,再次对结果文件进行扫描,查看替换过后的内容是否还有#define定义的符号,如果有,则重复上述处理过程
  • 1.宏参数和#define定义中可以出现其他#define定义的符号,但是对于宏,不能实现递归。
  • 2.当预处理器搜索#define定义的符号时,字符串常量的内容并不被搜索。

如何把参数插入到字符串中?

发现字符串是有自动相连的特点的

所以#VALUE会被预处理器在预处理阶段预处理为"VALUE"

接下来看看##的作用:

##可以把位于它两边的符号合成一个符号,并且允许宏定义从分离的文本片段创建标识符。

注意:连接之后产生的符号必须是已经定义的,否则结果就是非法的。

3.2.5带副作用的宏参数

当宏参数在宏的定义中出现超过一次的时候,如果参数带有副作用,那么在使用这个宏的时候就可能会出现危险,导致不可预测的后果。副作用就是表达式求值的时候出现的永久性后果。

如下代码可以证明副作用的宏参数带来的问题

 在代码预处理之后

3.2.6宏和函数对比

宏通常被用于执行简单的运算,比如在两个数中找出较大的一个

对于为什么不用函数来完成这个任务,有两个原因:

  • 1.用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间多,所以此时宏在程序的规模和运算方面更胜一筹。
  • 2.函数的参数必须声明为特定的类型,所以函数只能在类型合适的表达式上使用,而宏可以适用于整型,浮点型,长整型,宏是类型无关的
  • 1.每次使用宏的时候,会将宏定义的代码插入到程序中,除非宏比较短,否则可能大幅度增加程序的长度;
  • 2.宏是没法进行调试的,因为在预处理阶段,宏定义的符号已经发生了替换,此时调试看到的代码和实际上运行时的代码是有所差异的;
  • 3.宏由于类型无关,也就不够严谨了;
  • 4.宏可能会带来运算级优先的问题,导致程序容易出错; 

宏有时候也可以做到函数做不到的事情,比如宏的参数可以出现类型,但是函数不行

 预处理替换后:

总的来对比一下宏和函数的区别:

函数和宏的使用语法很相似,所以语言本身没法帮助区分二者,所以平时的命名习惯是:

这条指令用于移除一个宏定义

许多C 的编译器提供了一种能力,允许在命令行中定义符号。用于启动编译过程。
例如:当我们根据同一个源文件要编译出不同的一个程序的不同版本的时候,这个特性有点用处。(假定某个程序中声明了一个某个长度的数组,如果机器内存有限,我们需要一个很小的数组,但是另外一个机器内存大些,我们需要一个数组能够大些。)

在编译一个程序的时候如果要将一条语句或者一组语句编译或者放弃掉是很方便的,因为有一个叫条件编译的东西。

对于调试性的代码,删除比较可惜,保留又会碍事,所以可以选择性的去编译。

#include指令可以使另一个文件被编译,会让被包含的头文件出现在#include指令的地方

这种替换的方式很简单,预处理器会先删除这条指令,并用包含文件里的内容进行替换,如果这个文  件被包含了10次,那实际上就会被编译10次

3.6.1头文件被包含的方式

查找方法:先在源文件的目录下去查找,如果该头文件未被找到,编译器就会像去查找库函数的头文件一样在标准位置去查找头文件,如果还找不到就提示编译错误。

查找方法:直接在标准路径下去查找,如果找不到就提示编译错误。

虽然可以对库文件也采用""的包含方式,但是当目录下的文件非常多的时候,这样查找起来的效率就会低一些了,而且也不容易去区分是库文件还是头文件了。

3.6.2嵌套文件包含

这样最终的程序中就会包含两次common.h了,等于有2份common.h的内容,会造成代码的重复。

对此可以采用条件编译的方式来解决这个问题

在引用每个头文件时在开头写上这么一个内容:

如果下次还遇到包含头文件的代码,由于__STDUI_H__已经被定义过,所以也就不会进行第二次包含了

或者对于在头文件的开头也可以这么写:

也可以避免头文件的重复引入

第一章 管理信息系统概论

第二章 信息系统与组织

1、信息技术在组织结构模式变革中有哪些作用?

第三章 管理信息系统的技术基础

1、数据管理技术经历了哪些发展阶段,各有什么特点?

第四章 企业资源计划(ERP)

1、在ERP实施和应用过程中企业高层领导的作用是至关重要的。在下述的原因中哪一项是最确切的?
    C、对ERP项目负最终的责任,其决心和行动影响着员工思维方式和行为方式的改变

7、如下哪一项关于能力需求计划(CRP)的陈述是正确的?
    A、能力需求计划(CRP)对每个工作中心负荷和能力的匹配情况提供分时段的报告

8、ERP是在MRP的基础上发展起来的

9、ERP软件未来也将广泛使用云计算技术

10、ERP系统主要为企业提供财务管理服务

1、ERP的主要功能模块有哪些?

第五章 客户关系管理(CRM)

2、CRM是基于管理学、信息系统软件和互联网的,以有组织的方法帮助企业进行客户关系生命管理的信息系统。以下关于CRM的叙述中,( )是正确的

8、客户关系管理系统通常为销售、客户服务和市场营销活动提供软件与在线工具

9、客户关系管理软件未来也将广泛使用云计算技术

10、CRM系统主要为企业提供数据和分析工具来分析谁赚走了企业的钱

1、客户关系管理系统的结构分为哪三层?

第六章 供应链管理(SCM)

3、供应链管理是一种基于流程的集成化管理模式。( )

4、供应链管理追求整个供应链的总成本最低。( )

5、“纵向一体化”的企业注重自己的核心业务,充分发挥核心竞争优势,将非核心业务外包给其它企业。( )

6、供应链中,由于许多事情无法准确预测,不确定性总是存在的

7、供应链管理更多的是一种跨组织协同管理,管理难度较高

8、供应链的概念类似于传统的销售链,都是跨越组织边界,实现企业的盈利

9、供应链的结构模式比单个企业结构模式复杂

10、供应链管理系统的信息来自企业内部的MIS、DSS等信息系统

1、供应链管理与传统管理有何区别?

2、电子商务是网络经济的重要组成部分,以下关于电子商务的叙述中,( )是不正确的
    C、电子商务活动参与方不仅包括买卖方、金融机构、认证机构,还包括政府机构和配送中心
    D、电子商务是使用互联网等现代信息技术工具和在线支付方式进行商务活动,因此不包括网上做广告和网上调查活动。

5、当当网是典型的B to C电子商务网站。

6、电子商务使组织和个人之间的数字化商业交易成为可能

7、O2O模式实现了互联网与线下地面店的完美对接,是很有发展前景的电子商务模式

8、电子商务可以完全代替传统的线下实体店交易

9、移动电子商务具有移动性、便利性、个性化的特点

10、网络安全问题仍然是困扰电子商务发展的大问题

1、试辨析广义的电子商务和狭义的电子商务

第八章 知识管理与决策支持

1、下面哪一个是隐性知识的特点
    A、不易被认识到、不易衡量其价值、不易被其他人所理解和掌握
    B、可以通过正式的、系统化的方式(如书籍、出版物、计算机网络等)加以传播
    C、可以通过语言、文字、公式、计算机程序、数据库等编码方式表现出来
    D、存在于书本、计算机数据库、可以通过正式的、系统化的方式(如书籍、出版物、计算机网络等)加以传播CD-ROM等载体中

6、传统程序与专家系统的区别包括
    A、传统程序把关于问题求解的知识隐含于程序中,而专家系统则将知识(知识库)与运用知识的过程(推理机)分离开来
    B、传统程序主要面向数值计算和数据处理,专家系统则面向符号处理

9、专家系统的含义包括
    A、是一种具有智能的程序系统,能运用专家知识和经验进行推理的启发式程序系统。
    B、必须包含有大量专家水平的领域知识,并能在运行过程中不断地对这些知识进行更新。
    C、它能应用人工智能技术模拟人类专家求解问题的思维过程进行推理,解决相关领域内的困难问题,并且达到该领域专家的水平。

10、可以利用决策支持系统和计算机帮助决策者做出非结构化决策,只不过给出的决策可能是不确切或不准确的,同时将更多的过程留给了决策者。

1、决策问题按照结构化程度有哪些类型

第九章 信息系统战略规划与开发方法

10、系统开发的生命周期可划分为系统分析、系统设计、系统实施阶段。

1、试述结构化开发方法、原型法和面向对象方法的优缺点和适用范围

6、数据流程图为新系统提供了逻辑模型,综合地描述数据在系统中的流动、处理和存储情况。

7、在信息系统建设过程中,调查人员不仅要仔细倾听用户需求,还要注意观察用户行为。

8、数据流程图能够对系统数据的流向进行形象的描述,却不能对数据的细节加以描述,对数据细节的描述需要数据字典。

9、DFD图上除了有信息流还有物流

10、数据字典主要是对数据流程图上的数据流进行具体的定义

1、系统分析阶段的主要任务是什么?

第十一章 信息系统设计

9、屏幕界面是用户接触到的系统形象,是系统与用户之间的接口,也是控制和选择信息输入输出的主要途径,用户正是通过一个个的界面来了解和使用系统,从而实现系统的功能。

10、我国的居民身份证号是典型的助忆码。

1、系统设计阶段的任务有哪些?

第十二章 信息系统实施

6、Java语言是一种具有更面向对象的、跨平台的程序设计语言。

7、系统测试的目的是为了证明系统的正确性。

8、系统切换的任务就是保证新老系统进行平稳可靠的转换,最后使整个新系统正式交付使用。

9、黑盒测试方法是把软件看成一个透明的盒子,按照程序的内部结构和处理逻辑选定测试用例,对软件的逻辑路径及过程进行测试,检查与设计是否相符。

10、在系统切换的三种方法中,直接切换方法成本较低,风险较大

1、系统实施阶段的任务有哪些?

第十三章 信息系统项目管理

6、系统开发人员的主要工作是主持整个系统的建设、确定工作目标以及确定实现目标的具体方案。

7、一般甘特图的横方向表示工作,纵方向列出时间。

8、信息系统的成本估算是对完成项目工作所需要的费用进行估计和计划,要进行成本管理,必须先估算成本。

9、在信息系统设计中,由于用户与系统设计者有着不同的只是背景、兴趣和优先考虑的问题,这被称为用户—系统设计者鸿沟。

10、信息系统开发项目的工作计划一般在第一个层次按开发阶段安排,以做总体进度的控制,此层次宜采用关键路径发

1、信息系统项目有哪些特点?

第十四章 信息系统运行与管理

9、信息系统的日常运作管理是为了保证系统能长期有效地运作而进行的活动

10、按照加密钥和解密密钥是否相同,可将现有的加密体系分为两种:对称加密体制和非对称加密体制

1、信息系统的日常运行管理包括哪些内容?

第十五章 工资管理系统案例分析

1、试描述系统开发的一般流程和步骤

3、按照功能的不同,可以将一个系统中的所有要素分为四类,其中( )的功能是对整个系统各个环节的运行情况进行检测、检查,进而及时发现与实现系统目标相悖的问题,并做出适当的调整

38、电子商务是网络经济的重要组成部分,以下关于电子商务的叙述中,( )是不正确的
    C、电子商务活动参与方不仅包括买卖方、金融机构、认证机构,还包括政府机构和配送中心
    D、电子商务是使用互联网等现代信息技术工具和在线支付方式进行商务活动,因此不包括网上做广告和网上调查活动。

62、下面对现行系统详细调查的描述中,不正确的是()
    A、目的是明确问题与系统开发要解决的问题和目标,论证系统开发的必要性和可行性
    C、主要内容包括对现行系统的目标、主要功能、组织结构、业务流程、数据流程的调查和分析

82、关于数据与信息的关系,下列哪种说法不正确

96、及时性是信息第一位的、最基本、最核心的性质。

97、信息量的多少是根据人们的臆测来度量的。

98、信息、物质和能源是人类社会发展的三大资源。

99、安东尼模型是一种被普遍接受的从用户角度认识信息系统的理论。

100、TPS是针对企业各种事务的全面、集成的管理过程。

101、在电子数据处理阶段,应用计算机的主要目的是支持决策。

102、决策支持系统处理的业务与管理信息系统完全无关。

103、SIS指的是位于组织战略层的信息系统。

104、信息是经过加工过的数据,数据是信息的最重要的存在形式。

105、数据提供对客观事物的判断和解释。

106、信息按照管理层次可分为一次信息、二次信息、三次信息。

107、信息系统建设的组织结构取决于组织的管理风格。

108、企业的价值活动是一些孤立的活动。

109、信息系统对组织的影响巨大,而组织的变动却对信息系统毫无影响

110、信息技术是信息化生产力的重要组成部分。

111、组织变革的过程是一个渐进的过程。

112、信息系统在组织中的应用未来会越来越具有战略性作用

113、五力模型是波特提出的经典的竞争战略模型

114、在传统上,数据域是数据的最小单位

115、第一个数据库管理系统是层次数据库结构

116、使用DBMS,也不能保证完全消除数据冗余

117、使用DBMS,可以完全消除数据冗余。

118、计算机处理速度的进一步提高,能解决现实世界中的所有问题

119、一个数据库管理系统就是应用程序与数据之间的接口,它负责创建数据库

120、数据仓库中的数据是面向事务处理而不是面向某一主题的

121、数据库的出现从根本上杜绝了数据冗余,克服了传统文件系统的弊病

122、计算机处理速度的进一步提高,能解决现实世界中的所有问题

123、第一个数据库模型是关系数据库结构。

124、数据仓库和数据集市没有什么区别。

125、数据仓库是面向分析处理的

126、商务智能的核心技术是数据挖掘

127、在数据库系统中,应用程序可以直接从存储介质中获得所需的数据

128、MRP是在ERP的基础上发展起来的

129、ERP的根本特征是集成,即把组织内管理的各种职能整合在一起。

130、ERP体现了信息集成管理的思想

131、能力需求计划CRP的平衡对象是独立需求

132、相关需求是指需求量和需求时间由企业外部的需求决定的那部分物料需求。

133、企业的价值活动是一些孤立的活动

134、CRM软件中,操作层的功能强弱对系统的业务处理能力有较大影响

135、CRM软件的核心是分析层功能,但接触层也很重要

136、供应链管理是一种基于流程的集成化管理模式。

137、供应链管理与传统管理的很大不同就是实现了链上节点的协同运作

138、京东网是典型的C to C电子商务网站

139、阿里巴巴是典型的BtoC电子商务网站

140、半结构化或非结构化的决策问题,应该用管理信息系统来解决

141、决策支持系统更应该关注系统的数据处理能力,而不是其交互性

142、MIS中普遍使用了决策模型,它们主要用于解决非结构化决策问题。

143、专家系统所拥有的知识面一般很宽,因此可以辅助企业解决大部分问题

144、组织采用信息系统之前必须注意业务流程的优化和调整。

145、BSP规划法的优点是它能保证信息系统与企业的组织结构的一致。

146、信息系统战略规划就是规划信息系统的组成架构

147、原型法适用于大型或复杂性高的信息系统的开发

148、信息系统的生命周期就是系统开发的生命周期

149、诺兰模型的第二阶段是蔓延阶段

150、结构化系统开发方法的优点是开发周期短、灵活性强

151、关键影响因素指那些对组织能否成功实现其目标起决定作用的因素

152、CSF方法中,关键性能指标的确定应在关键成功因素分析之前

153、可行性分析的最终结果也可能是暂缓开发信息系统

154、表达新系统逻辑方案的主要工具是数据字典

155、系统分析阶段的任务是解决“怎么做”的问题

156、对信息系统建设来说,可行性分析与系统开发可同步进行

157、数据流程图绘制的基本思想是:自顶向下,逐步细化。

158、信息系统可以按组织结构来规划设计其结构

159、系统设计阶段的任务是解决“怎么做”的问题

160、程序编写是在信息系统设计阶段进行的

161、身份证号从代码的分类上属于顺序码

162、系统测试的目的是为了证明系统的正确性

163、一个合理的模块划分应该是模块间尽可能随意

164、服务等级协议是面向业务的,一般不包含详细的技术说明

165、软件项目管理不同于一般的工程项目管理

166、成功的软件实施需要软件系统知识和企业管理思想紧密结合

167、信息系统的建设是典型的一把手工程,主要领导必须参与

  Java 堆是用来存储对象实例的, 因此如果我们不断地创建对象, 并且保证 GC Root 和创建的对象之间有可达路径以免对象被垃圾回收, 那么当创建的对象过多时, 会导致 heap 内存不足, 进而引发 OutOfMemoryError 异常。

  上面是一个引发 OutOfMemoryError 异常的代码, 我们可以看到, 它就是通过不断地创建对象, 并将对象保存在 list 中防止其被垃圾回收, 因此当对象过多时, 就会使堆内存溢出。

  编译运行上述代码后, 会有如下输出:

  堆内存溢出的时候,虚拟机会抛出java.lang.OutOfMemoryError:java heap space,出现此种情况的时候,我们需要根据内存溢出的时候产生的dump文件来具体分析(需要增加-XX:+HeapDumpOnOutOfMemoryErrorjvm启动参数)。出现此种问题的时候有可能是内存泄露,也有可能是内存溢出了。

  如果内存泄露,我们要找出泄露的对象是怎么被GC ROOT引用起来,然后通过引用链来具体分析泄露的原因。

  如果出现了内存溢出问题,这往往是程序本生需要的内存大于了我们给虚拟机配置的内存,这种情况下,我们可以采用调大-Xmx来解决这种问题。

  下面我们通过如下的代码来演示一下此种情况的溢出:

  我们通过如下的命令运行上面的代码:

  程序输入如下的信息:

  从运行结果可以看出,JVM进行了一次Minor gc和两次的Major gc,从Major gc的输出可以看出,gc以后old区使用率为134K,而字节数组为10M,加起来大于了old generation的空间,所以抛出了异常,如果调整-Xms21M,-Xmx21M,那么就不会触发gc操作也不会出现异常了。

  我们知道, JVM 的运行时数据区中有一个叫做 虚拟机栈 的内存区域, 此区域的作用是: 每个方法在执行时都会创建一个栈帧, 用于存储局部变量表, 操作数栈, 方法出口等信息。

  因此我们可以创建一个无限递归的递归调用, 当递归深度过大时, 就会耗尽栈空间, 进而导致了 StackOverflowError 异常。

  下面是具体的代码:

  当编译运行上述的代码后, 会输出如下异常信息:

  栈溢出抛出java.lang.StackOverflowError错误,出现此种情况是因为方法运行的时候栈的深度超过了虚拟机容许的最大深度所致。

  出现这种情况,一般情况下是程序错误所致的,比如写了一个死递归,就有可能造成此种情况。 下面我们通过一段代码来模拟一下此种情况的内存溢出。

  运行上面的代码,会抛出如下的异常:

  通过上面的实验其实也从侧面验证了一个结论:当对象大于新生代剩余内存的时候,将直接放入老年代,当老年代剩余内存还是无法放下的时候,出发垃圾收集,收集后还是不能放下就会抛出内存溢出异常了

  我们知道Hotspot jvm通过持久带实现了Java虚拟机规范中的方法区,而运行时的常量池就是保存在方法区中的,因此持久带溢出有可能是运行时常量池溢出,也有可能是方法区中保存的class对象没有被及时回收掉或者class信息占用的内存超过了我们配置。当持久带溢出的时候抛出java.lang.OutOfMemoryError: PermGen space。

  我在工作可能在如下几种场景下出现此问题。

  使用一些应用服务器的热部署的时候,我们就会遇到热部署几次以后发现内存溢出了,这种情况就是因为每次热部署的后,原来的class没有被卸载掉。

  如果应用程序本身比较大,涉及的类库比较多,但是我们分配给持久带的内存(通过-XX:PermSize和-XX:MaxPermSize来设置)比较小的时候也可能出现此种问题。

  一些第三方框架,比如spring,hibernate都通过字节码生成技术(比如CGLib)来实现一些增强的功能,这种情况可能需要更大的方法区来存储动态生成的Class文件。

  我们知道Java中字符串常量是放在常量池中的,String.intern()这个方法运行的时候,会检查常量池中是否存和本字符串相等的对象,如果存在直接返回对常量池中对象的引用,不存在的话,先把此字符串加入常量池,然后再返回字符串的引用。那么我们就可以通过String.intern方法来模拟一下运行时常量区的溢出。下面我们通过如下的代码来模拟此种情况:

  我们通过如下的命令运行上面代码:

  运行后的输入如下图所示:

  通过上面的代码,我们成功模拟了运行时常量池溢出的情况,从输出中的PermGen space可以看出确实是持久带发生了溢出,这也验证了,我们前面说的Hotspot jvm通过持久带来实现方法区的说法。

  程序创建的线程数超过了操作系统的限制。对于Linux系统,我们可以通过ulimit -u来查看此限制。

  给虚拟机分配的内存过大,导致创建线程的时候需要的native内存太少。我们都知道操作系统对每个进程的内存是有限制的,我们启动Jvm,相当于启动了一个进程,假如我们一个进程占用了4G的内存,那么通过下面的公式计算出来的剩余内存就是建立线程栈的时候可以用的内存。 线程栈总可用内存=4G-(-Xmx的值)- (-XX:MaxPermSize的值)- 程序计数器占用的内存 通过上面的公式我们可以看出,-Xmx 和 MaxPermSize的值越大,那么留给线程栈可用的空间就越小,在-Xss参数配置的栈容量不变的情况下,可以创建的线程数也就越小。因此如果是因为这种情况导致的unable to create native thread,那么要么我们增大进程所占用的总内存,或者减少-Xmx或者-Xss来达到创建更多线程的目的。

  JVM内存区域组成

  简单的说java中的堆和栈

  java把内存分两种:一种是栈内存,另一种是堆内存

  1。在函数中定义的基本类型变量和对象的引用变量都在函数的栈内存中分配;

  2。堆内存用来存放由new创建的对象和数组

  在函数(代码块)中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的内存空间;在堆中分配的内存由java虚拟机的自动垃圾回收器来管理

  堆的优势是可以动态分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的。缺点就是要在运行时动态分配内存,存取速度较慢;

  栈的优势是存取速度比堆要快,缺点是存在栈中的数据大小与生存期必须是确定的无灵活性。

  新创建的对象被分配到New区,当该区被填满时会被GC辅助线程移到Old区,当Old区也填满了会触发GC主线程遍历堆内存里的所有对象。Old区的大小等于Xmx减去-Xmn

  每个线程都有他自己的Stack

我要回帖

更多关于 软件编程代码 的文章

 

随机推荐