热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

jvm内存结构的原理及应用

这篇文章主要讲解了“jvm内存结构的原理及应用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“

这篇文章主要讲解了“jvm内存结构的原理及应用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“jvm内存结构的原理及应用”吧!

jvm内存结构概述

jvm内存结构的原理及应用
  jvm内存结构主要包括:方法区、堆、虚拟机栈、本地方法栈、程序计数器等五大部分, 下面我们来具体看一下每一个部分。

1.1 虚拟机栈

  • 作用:
    虚拟机栈描述的是java方法执行的动态内存模型,通过进栈、出栈来实现方法的调用结构。

  • 分析:
      栈结构的特点是后进先出,方法调用的过程也是后调用的方法返回结果后,先调用的方法再接着执行,你是干柴,我是烈火。你是鱼儿,我是小河。(此处不知道是蛋孵化了鸡,还是鸡生出了蛋)

  以methodA调用methodB为例,来看一下方法栈的执行过程 jvm内存结构的原理及应用
首先是主方法进入空栈(图中免去了这一步),主方法中调用methodA --》 methodA入栈 --》 methodA调用methodB --》 methodB入栈 --》 methodB执行完毕,出栈并返回返回值 --》 methodA执行完毕,出栈并返回返回值 --》主线程执行完毕并出栈(图中免去了这一步)--》程序执行完毕。
  那么methodA、methodB中到底包含了哪些内容呢?
  我们不如从方法定义的角度来思考一下,编写程序时,里面经常出现的几个要素无外乎:变量、控制结构(循环、分支)、函数调用(也可以叫方法),函数其实就是用一定的控制结构来操作变量,中间穿插着其他函数的调用,分支结构主要控制的是程序执行到哪一行,这个由我们后面1.5章节要讲到的程序计数器来实现,函数调用层次如上面所说由虚拟机栈来支持,而变量以及方法的出口就是methodA、methodB中的主要内容。
  methodA、methodB在虚拟机栈中叫做栈帧,栈帧中包括变量(局部变量表-基本类型、对象引用-对象内存地址等)以及返回值地址等信息,可以看出栈帧中包含的内容是编译器就可确定大小的,当进入一个方法时,需要分配多大的局部变量空间是完全确定的,在运行期中不会改变局部变量表的大小。

  • 此区域可能出现的异常:
    栈是有深度的,方法调用层次超过栈的深度,就会出现StackoverflowError,一般是递归调用时,基线条件不合理时,容易出现此问题。
    当栈的深度增大时,所需要的局部变量表空间也随之增长,当超过一定界限时,会出现OutOfMemoryError异常。

1.2 本地方法栈

  • 作用:
    本地方法栈与虚拟机栈的区别是调用的是不同类型的方法,本地方法栈用于记录native方法的调用,本地方法栈中未对native方法实现语言、数据结构等做强制规定,主要由虚拟机自己定义并实现。

  • 注:
    由于本地方法栈和虚拟机栈的作用非常相似,因此部分虚拟机的实现中,就将这两块区域合并成了一个区域,例如比较常用的Hotspot。

  • 此区域可能出现的异常
    与虚拟机栈相同,此区域也有可能出现StackoverflowError或OutOfMemoryError。

1.3 堆

  • 作用:
    堆是jvm是管理的内存中最大的一块,此区域只有一个作用就是存放对象实例。(java是面向对象语言--》堆用于存放对象实例 --》堆占用空间最大,嗯,没毛病铁子。)

  • 注 :
    由于此区域占用内存空间最大,而且对象的创建与销毁是比较频繁的,那内存空间不够用了怎么办?跟杀猪挑最肥的宰是一个道理,此区域是垃圾回收的主要区域。java为我们省去了代码层手动释放内存的工作,通过垃圾回收器来实现自动化的内存回收(《7天精通java》:《21天c++从入门到入土》,知道自动垃圾回收的重要性了吧)

  • 此区域可能出现的异常:
    为对象分配空间时,内存不足,会出现OutOfMemoryError(敲黑板)。
    对应的排查策略:配置参数-XX:+HeapDumpOnOutOfMemoryError,这样虚拟机在出现此异常时,会生成内存堆存储快照,使用工具Eclipse Memory Analyzer或jprofiler,可以分析某些对象占用空间百分比,快速定位到问题,如果代码存在问题,例如不停的创建某些对象,但并不释放,那就要通过修改代码来解决问题,如果代码不存在问题,就需要通过加大物理内存,调整jvm堆参数来增加堆大小。(-Xms 堆初始化大小,-Xms 对空间最大大小,实际配置过程中,一般设置成一样的大小,避免出现内存抖动,影响稳定性)

1.4 方法区

  • 作用:
    方法区主要用于存取类信息、常量、静态变量、运行时常量池等。

  • 分析:
    运行时常量池用于存取字面量和符号引用,当使用双引号声明String变量时,此变量并不是开辟到堆空间当中,而是开辟到方法区中的运行时常量池中的,运行时常量池不仅可以在编译期产生,也可以在程序运行期间,动态产生,例如String中的intern方法,就是在程序运行状态中将字符串值放到运行时常量池中的。

  • 此区域可能出现的异常:
    此区域在内存不足时,也会出现OutOfMemoryError异常。

1.5 程序计数器

  • 作用:
    程序计数器主要是用于记录当前线程所执行的字节码的行号指示器,即当前线程执行到了哪一行,由于功能比较简单,所以与其他几个区域相比,内存空间占用的非常小。

  • 此区域可能出现的异常:
    程序计数器的作用决定了在此区域中不会出现由程序本身导致的异常,如果此处出现异常,是jvm本身的设计缺陷。

  • 注:
    如果线程执行的是java方法,计数器对应的是字节码指令的地址,但是如果是native方法,底层是非java实现的,此时计数器对应的值是undefined

  • 引申:
    说到了程序计数器,在部分编程语言中,是支持goto关键字的,goto可以让程序直接跳转到指定行,java是不支持goto的,但是把goto作为了保留字,即java不支持此种语法,但是也不让开发者去定义为变量,防止后续java发展过程中,加入goto关键字后,导致部分程序运行异常。

1.6 线程共享区与线程独占区

  上面五个区域中,方法区和堆是线程共享的区域,这两个区域中放置的内容是与线程无关的,任意一个线程都可能会访问到这两块区域中的内容。
  对于每个线程来说,它的调用方法栈应该是独属于某个线程的,如果多个线程共用一个方法栈那程序的执行顺序是无法得到保障的,线程执行到哪一行应该也是唯一的,因此方法栈、程序计数器是线程独占的。

感谢各位的阅读,以上就是“jvm内存结构的原理及应用”的内容了,经过本文的学习后,相信大家对jvm内存结构的原理及应用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程笔记,小编将为大家推送更多相关知识点的文章,欢迎关注!


推荐阅读
  • 初识java关于JDK、JRE、JVM 了解一下 ... [详细]
  • 生产环境下JVM调优参数的设置实例
     正文前先来一波福利推荐: 福利一:百万年薪架构师视频,该视频可以学到很多东西,是本人花钱买的VIP课程,学习消化了一年,为了支持一下女朋友公众号也方便大家学习,共享给大家。福利二 ... [详细]
  • 本文介绍了在多平台下进行条件编译的必要性,以及具体的实现方法。通过示例代码展示了如何使用条件编译来实现不同平台的功能。最后总结了只要接口相同,不同平台下的编译运行结果也会相同。 ... [详细]
  • Java程序设计第4周学习总结及注释应用的开发笔记
    本文由编程笔记#小编为大家整理,主要介绍了201521123087《Java程序设计》第4周学习总结相关的知识,包括注释的应用和使用类的注释与方法的注释进行注释的方法,并在Eclipse中查看。摘要内容大约为150字,提供了一定的参考价值。 ... [详细]
  • Week04面向对象设计与继承学习总结及作业要求
    本文总结了Week04面向对象设计与继承的重要知识点,包括对象、类、封装性、静态属性、静态方法、重载、继承和多态等。同时,还介绍了私有构造函数在类外部无法被调用、static不能访问非静态属性以及该类实例可以共享类里的static属性等内容。此外,还提到了作业要求,包括讲述一个在网上商城购物或在班级博客进行学习的故事,并使用Markdown的加粗标记和语句块标记标注关键名词和动词。最后,还提到了参考资料中关于UML类图如何绘制的范例。 ... [详细]
  • 使用eclipse创建一个Java项目的步骤
    本文介绍了使用eclipse创建一个Java项目的步骤,包括启动eclipse、选择New Project命令、在对话框中输入项目名称等。同时还介绍了Java Settings对话框中的一些选项,以及如何修改Java程序的输出目录。 ... [详细]
  • 开发笔记:Python之路第一篇:初识Python
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Python之路第一篇:初识Python相关的知识,希望对你有一定的参考价值。Python简介& ... [详细]
  • Maven构建Hadoop,
    Maven构建Hadoop工程阅读目录序Maven安装构建示例下载系列索引 序  上一篇,我们编写了第一个MapReduce,并且成功的运行了Job,Hadoop1.x是通过ant ... [详细]
  • 这篇文章主要讲解了“如何应对Android面试”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何应对 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • switch语句的一些用法及注意事项
    本文介绍了使用switch语句时的一些用法和注意事项,包括如何实现"fall through"、default语句的作用、在case语句中定义变量时可能出现的问题以及解决方法。同时也提到了C#严格控制switch分支不允许贯穿的规定。通过本文的介绍,读者可以更好地理解和使用switch语句。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
author-avatar
大绿
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有