一、虚拟机栈(VM Stack)

1.1)什么是虚拟机栈

  虚拟机栈是用于描述java方法执行的内存模型。
  每个java方法在执行时,会创建一个“栈帧(stack frame)”,栈帧的结构分为“局部变量表、操作数栈、动态链接、方法出口”几个部分(具体的作用会在字节码执行引擎章节中讲到,这里只需要了解栈帧是一个方法执行时所需要数据的结构)。我们常说的“堆内存、栈内存”中的“栈内存”指的便是虚拟机栈,确切地说,指的是虚拟机栈的栈帧中的局部变量表,因为这里存放了一个方法的所有局部变量。
  方法调用时,创建栈帧,并压入虚拟机栈;方法执行完毕,栈帧出栈并被销毁,如下图所示:

1.2)虚拟机栈的特点

  虚拟机栈是线程隔离的,即每个线程都有自己独立的虚拟机栈。

1.3)虚拟机栈的StackOverflowError

  若单个线程请求的栈深度大于虚拟机允许的深度,则会抛出StackOverflowError(栈溢出错误)。
  JVM会为每个线程的虚拟机栈分配一定的内存大小(-Xss参数),因此虚拟机栈能够容纳的栈帧数量是有限的,若栈帧不断进栈而不出栈,最终会导致当前线程虚拟机栈的内存空间耗尽,典型如一个无结束条件的递归函数调用,代码见下:
 /**
* java栈溢出StackOverFlowError
* JVM参数:-Xss128k
* Created by chenjunyi on 2018/4/25.
*/
public class JavaVMStackSOF { private int stackLength = -1; //通过递归调用造成StackOverFlowError
public void stackLeak() {
stackLength++;
stackLeak();
} public static void main(String[] args) {
JavaVMStackSOF oom = new JavaVMStackSOF();
try {
oom.stackLeak();
} catch (Throwable e) {
System.out.println("Stack length:" + oom.stackLength);
e.printStackTrace();
}
} }
  设置单个线程的虚拟机栈内存大小为128K,执行main方法后,抛出了StackOverflow异常
 Stack length:983
java.lang.StackOverflowError
at com.manayi.study.jvm.chapter2._02_JavaVMStackSOF.stackLeak(_02_JavaVMStackSOF.java:14)
at com.manayi.study.jvm.chapter2._02_JavaVMStackSOF.stackLeak(_02_JavaVMStackSOF.java:15)
at com.manayi.study.jvm.chapter2._02_JavaVMStackSOF.stackLeak(_02_JavaVMStackSOF.java:15)
······

1.4)虚拟机栈的OutOfMemoryError

  不同于StackOverflowError,OutOfMemoryError指的是当整个虚拟机栈内存耗尽,并且无法再申请到新的内存时抛出的异常。
  JVM未提供设置整个虚拟机栈占用内存的配置参数。虚拟机栈的最大内存大致上等于“JVM进程能占用的最大内存(依赖于具体操作系统) - 最大堆内存 - 最大方法区内存 - 程序计数器内存(可以忽略不计) - JVM进程本身消耗内存”。当虚拟机栈能够使用的最大内存被耗尽后,便会抛出OutOfMemoryError,可以通过不断开启新的线程来模拟这种异常,代码如下:
 **
* java栈溢出OutOfMemoryError
* JVM参数:-Xss2m
* Created by chenjunyi on 2018/4/25.
*/
public class JavaVMStackOOM { private void dontStop() {
while (true) {
}
} //通过不断的创建新的线程使Stack内存耗尽
public void stackLeakByThread() {
while (true) {
Thread thread = new Thread(() -> dontStop());
thread.start();
}
} public static void main(String[] args) {
JavaVMStackOOM oom = new _03_JavaVMStackOOM();
oom.stackLeakByThread();
} }
  设置单个线程虚拟机栈的占用内存为2m并不断生成新的线程,最终虚拟机栈无法申请到新的内存,抛出异常:
 Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread

二、本地方法栈(Native Method Stack)

  本地方法栈的功能和特点类似于虚拟机栈,均具有线程隔离的特点以及都能抛出StackOverflowError和OutOfMemoryError异常。
  不同的是,本地方法栈服务的对象是JVM执行的native方法,而虚拟机栈服务的是JVM执行的java方法。如何去服务native方法?native方法使用什么语言实现?怎么组织像栈帧这种为了服务方法的数据结构?虚拟机规范并未给出强制规定,因此不同的虚拟机实可以进行自由实现,我们常用的HotSpot虚拟机选择合并了虚拟机栈和本地方法栈。

02-JVM内存模型:虚拟机栈与本地方法栈的更多相关文章

  1. JVM 运行时数据区:程序计数器、Java 虚拟机栈和本地方法栈,方法区、堆以及直接内存

    Java 虚拟机可以看作一台抽象的计算机,如同真实的计算机,它也有自己的指令集和运行时内存区域. Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存(运行时内存区域)划分为若干个不同的数 ...

  2. 【JVM第三篇--运行时数据区】程序计数器、虚拟机栈、本地方法栈

    写在前面的话:本文是在观看尚硅谷JVM教程后,整理的学习笔记.其观看地址如下:尚硅谷2020最新版宋红康JVM教程 一.运行时数据区 我们在编写Java程序时,使用JVM的流程主要如下所示: 虚拟机在 ...

  3. JVM方法栈的工作过程,方法栈和本地方法栈有什么区别。

    JVM的本地方法栈   对于一个运行中的Java程序而言,它还可能会用到一些跟本地方法相关的数据区.当某个线程调用一个本地方法时,它就进入了一个全新的并且不再受虚拟机限制的世界.本地方法可以通过本地方 ...

  4. Java虚拟机栈和本地方法栈

    Java虚拟机栈的特征 线程私有 后进先出(LIFO)栈 存储栈帧,支持Java方法的调用.执行和退出 可能出现OutOfMemoryError异常和StackOverflowError异常 Java ...

  5. 从几个sample来学习JAVA堆、方法区、JAVA栈和本地方法栈

    最近在看<深入理解Java虚拟机>,书中给了几个例子,比较好的说明了几种OOM(OutOfMemory)产生的过程,大部分的程序员在写程序时不会太关注Java运行时数据区域的结构: 感觉有 ...

  6. jvm:内存结构(堆、方法区、程序计数器、本地方法栈、虚拟机栈)

    1.jvm内存结构 静态编译:把java源文件编译成字节码文件class,这个时候class文件以静态方式存在. 类加载器:把java字节码文件加载到内存中 方法区:将字节码放到方法区作为元数据(简单 ...

  7. Java虚拟机(二):JVM内存模型

    所有的Java开发人员可能会遇到这样的困惑?我该为堆内存设置多大空间呢?OutOfMemoryError的异常到底涉及到运行时数据的哪块区域?该怎么解决呢?其实如果你经常解决服务器性能问题,那么这些问 ...

  8. 深入理解java虚拟机学习笔记(一)JVM内存模型

    上周末搬家后,家里的宽带一直没弄好,跟电信客服反映了N遍了终于约了个师傅明天早上来迁移宽带,可以结束一个多星期没网的痛苦日子了.这段时间也是各种忙,都一个星期没更新博客了,再不写之前那种状态和激情都要 ...

  9. JVM内存模型总结,有各版本JDK对比、有元空间OOM监控案例、有Java版虚拟机,综合实践学习!

    作者:小傅哥 博客:https://bugstack.cn Github:https://github.com/fuzhengwei/CodeGuide/wiki 沉淀.分享.成长,让自己和他人都能有 ...

随机推荐

  1. thinkphp 和 laravel使用sql语句操作db和源码浅析

    thinkphp 和 laravel是phper开发中用的比较多的两个框架,无所谓好坏,看个人习惯及喜爱! 前言对于一个PHP应用,可能最多的就是操作数据,以致于初学者有时只把php当做数据库增删查改 ...

  2. PAT——1018. 锤子剪刀布

    大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示: 现给出两人的交锋记录,请统计双方的胜.平.负次数,并且给出双方分别出什么手势的胜算最大. 输入格式: 输入第1行给出正整数N( ...

  3. java soa接口测试,可以使用http协议调用

    post调用url:“接口url”+/rpc post调用参数body: { "ver": "接口版本号", "soa":{"re ...

  4. php开发微信图灵机器人

    本着开源为原则,为这个世界更美好作出一份共享,我就给大家做个指路人,如果实用,记得给提供开源的朋友一些鼓励. 简单介绍一下实现思路,使用swoole扩展接管php运行,由于swoole只能在类UNIX ...

  5. Unity3D Errors And Fix

    Author Error: Shader warning in 'Custom/ShowAnimation': Not enough temporary registers, needs 9 (com ...

  6. 安装mysql zip 安装包 Navicat连接

    笔者在安装mysql时一直出现各种问题,今天难得成功一次,决定记录一下,留作纪念与参考 安装第一步,下载mysql https://dev.mysql.com/downloads/mysql/ 以在w ...

  7. 5 替换空格 JavaScript

    题目描述 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy.   原来一个空格字符,替换之后 ...

  8. jquery仿移动端支付宝键盘

    最近做项目时碰到一个需求,就是在移动端支付页面点击支付按钮弹出一个支付键盘,类似于支付宝的那种.由于项目只是单纯的手机网站,而并非app,所以这个功能得由前端来实现.话不多说,先上图看看效果. 尼玛, ...

  9. OAuth2.0 与 oauth2-server 库的使用

    作者:baiyi链接:https://www.jianshu.com/p/83b0f6d82d6c來源:简书 OAuth2.0 是关于授权的开放网络标准,它允许用户已第三方应用获取该用户在某一网站的私 ...

  10. 『Linux基础 - 3』 Linux文件目录介绍

    Windows 和 Linux 文件系统区别 -- 结构 Windows 下的文件系统 - 在 Windows 下,打开 "计算机",我们看到的是一个个的驱动器盘符: - 每个驱动 ...