java虚拟机 jvm 出入java栈 栈空间内存分配
java栈空间是一块线程私有的内存空间,java堆和程序数据密切相关,那么java栈就是和线程执行密切相关。线程最基本的执行行为就是函数的调用。每次函数调用其实是通过java栈传递数据的。
数据结构中的栈的特性:先进后出,后进先出。FIFO.
java内存中的栈跟数据结构中的特性相似也是FIFO.但是只支持进栈和出栈操作。
java栈中保存的主要内容是栈帧。每一次函数调用都会有对应的栈帧被压进去java栈,执行完毕的时候被弹出java栈。如下图所示。
函数1对应栈帧1,函数2对应栈帧2.函数3对应栈帧3.以此类推。
函数1调用函数2,函数2调用函数3,函数3调用函数4,以此类推。
函数1被调用的时候栈帧1入栈,函数2被调用的时候栈帧2入栈,以此类推。
所以最后被调用的函数在栈顶,也是最先被弹出栈的。
每一个栈帧保存着函数的局部变量、中间运算结果等数据。
函数返回的时候,栈帧从java栈弹出。什么时候函数返回呢?两种情况:
1.正常的return的时候。
2.程序抛出异常。
在一个栈帧内,至少包含局部变量表、操作数帧和帧数据区几部分。
思考的问题:没一次函数调用生成栈帧,从而肯定会占用一定的栈空间。所以栈空间内存不足的时候,函数调用无法进行。当请求的栈深度大于最大栈深度的时候系统会抛出StackOverflowError异常。(内存溢出会在以后的章节深入的讲解和汇总)
java虚拟机制定线程的最大栈空间参数为-Xss,这个参数决定了函数调用的最大深度。
下面一段代码说明,是一个没有出口的递归。这段代码可能会栈溢出错误。如下所示:
private static int count=0; public static void recursion(){ count++; recursion(); } public static void main(String[] args) { try { recursion(); } catch (Exception e) { System.out.println("deep of calling="+count); e.printStackTrace(); } }
使用参数-Xss128K执行代码,结果如下:
deep of calling=2020 Exception in thread "main" java.lang.StackOverflowError at cn.xhgg.test.TestStackDeep.recursion(TestStackDeep.java:6)
使用参数-Xss256K执行代码,结果如下:
count=3665 Exception in thread "main" java.lang.StackOverflowError at sun.nio.cs.UTF_8.updatePositions(UTF_8.java:77)
两次内存不同对比:
内存增大很明显调用次数增加了。
结论:
函数嵌套的层数很大程度上有栈的大小决定的。栈越大,函数调用的次数就越多。
什么因素影响函数在栈中内存大大小呢?下一个章节介绍(java虚拟机jvm局部变量表)
java虚拟机 jvm 出入java栈 栈空间内存分配的更多相关文章
- 深入理解java虚拟机(2)------垃圾收集器和内存分配策略
GC可谓是java相较于C++语言,最大的不同点之一. 1.GC回收什么? 上一篇讲了内存的分布. 其中程序计数器栈,虚拟机栈,本地方法栈 3个区域随着线程而生,随着线程而死.这些栈的内存,可以理解为 ...
- 深入了解Java虚拟机(2)垃圾收集器与内存分配策略
垃圾收集器与内存分配策略 由于JVM中对象的频繁操作是在堆中,所以主要回收的是堆内存,方法区中的回收也有,但是比较谨慎 一.对象死亡判断方法 1.引用计数法 就是如果对象被引用一次,就给计数器+1,否 ...
- <<深入Java虚拟机>>-第三章-垃圾收集器与内存分配策略-学习笔记
垃圾收集 垃圾收集(Garbage Collection,GC),垃圾收集需要完成的三件事情. 哪些对象需要回收 什么时候回收 如何回收 如何确定对象已死(即不可能在被任何途径引用的对象) 引用计数算 ...
- java虚拟机(二)--垃圾收集器与内存分配策略
1.判断对象是否存活的算法: 1.1.引用计数算法:给对象添加一个引用计数器,每当有一个地方引用他时,计数器+1,当引用失效时,计数器-1,任何时刻计数器为0的对象就是不可能再被引用的,但是他很难解决 ...
- 《深入理解Java虚拟机》读书笔记-垃圾收集器与内存分配策略
在堆里存放着java世界中几乎所有的对象实例,垃圾收集器在对堆进行回收前需要知道哪些对象还存活,哪些对象已经死去.那怎么样去判断对象是否存活呢? 一.判断对象是否存活算法 1.引用计数法 实现思路:给 ...
- Java虚拟机学习(4):对象内存分配与回收
对象优先在Eden上分配 大多数情况下,对象优先在新生代Eden区域中分配.当Eden内存区域没有足够的空间进行分配时,虚拟机将触发一次 Minor GC(新生代GC).Minor GC期间虚拟机将E ...
- [Note][深入理解Java虚拟机] 第三章 垃圾收集器与内存分配策略笔记
书上关于GCTimeRatio的讲解有点难以理解,查看Oracle的文档后重新理解了下 -XX:GCTimeRatio 运行时间 / GC时间 当GCTimeRatio为19时,运行时间是GC时间的1 ...
- 深入解析java虚拟机-jvm运行机制
转自oschina 一:JVM基础概念 JVM(Java虚拟机)一种用于计算设备的规范,可用不同的方式(软件或硬件)加以实现.编译虚拟机的指令集与编译微处理器的指令集非常类似.Java虚拟机包括一套字 ...
- 【java虚拟机系列】java虚拟机系列之JVM总述
我们知道java之所以能够快速崛起一个重要的原因就是其跨平台性,而跨平台就是通过java虚拟机来完成的,java虚拟机属于java底层的知识范畴,即使你不了解也不会影响绝大部分人从事的java应用层的 ...
随机推荐
- [Codeforces 946F]Fibonacci String Subsequences
Description 题库链接 定义 \(F(x)\) 为 \(F(x-1)\) 与 \(F(x-2)\) 的连接(其中 \(F(0) = "0",F(1) = "1& ...
- [Spoj]Counting Divisors (cube)
来自FallDream的博客,未经允许,请勿转载,谢谢. 设d(x)表示x的约数个数,求$\sum_{i=1}^{n}d(i^{3})$ There are 5 Input files. - Inpu ...
- Unity脚本自动添加注释脚本及排版格式
Unity脚本自动添加注释脚本及头部注释排版格式 公司开发项目,需要声明版权所有,,,,标注公司名,作者,时间,项目名称及描述等等. 自己总结实现的现成脚本及头部注释排版文本,添加到模版即可. 文件不 ...
- 在Cisco Catalyst 3750端口做策略限速 QOS
今天任务是在3750上限制端口的速率,本来以为是很简单的事,speed命令搞定,敲进去才知道speed命令只能叫端口速率改成10M或100M,也就是说只能起到端口高低速率的切换功能,不能自定义速率,后 ...
- SCNN车道线检测--(SCNN)Spatial As Deep: Spatial CNN for Traffic Scene Understanding(论文解读)
Spatial As Deep: Spatial CNN for Traffic Scene Understanding 收录:AAAI2018 (AAAI Conference on Artific ...
- sqlserver批量更新数据
update t_hr_teadept set rjkm=b.yjkmfrom t_hr_teadept a inner join t_tr_bzxx_km b on a.bzh=b.bzh wher ...
- redux 最简例子
方便初学redux的同学学习,这里是最简单的redux例子 1 import React, {Component, PropTypes} from 'react' 2 import ReactDOM ...
- 补充Mysql5.7用法
下面简单介绍一下安装: [root@MySQL soft]# tar xf mysql-5.7.10-linux-glibc2.5-x86_64.tar.gz -C /data/service/ [r ...
- Lucene——Field.Store(存储域选项)及Field.Index(索引选项)
Field.Store.YES或者NO(存储域选项) 设置为YES表示或把这个域中的内容完全存储到文件中,方便进行文本的还原 设置为NO表示把这个域的内容不存储到文件中,但是可以被索引,此时内容无法完 ...
- LintCode题解之最长单词
这些一次遍历搞定的,套路无非都是在遍历的时候就记录数据的状态,然后根据遍历到的当前的数据的状态来修改最终结果,当遍历完了的时候结果也就确定了. public class Solution { /* * ...