当前位置: 首页 > news >正文

JVM 内存解析,以及自己的一些见解

Java虚拟机所管理的内存将会包括以下几个运行时数据区域

程序计数器( Program Counter Register)
首先程序计数器是一块机比较小的存储空间,也是当前线程私有的一段存储空间,用于记录当前线程执行代码的行数,通俗来讲一个线程会有一个程序计数器,来控制代码运行到了哪一行,字节码解释器工作的时候,就是告诉程序计数器下一条指令执行哪一行的代码,从而控制了,分支(swtich),循环(while),异常(exception),判断(if ),跳转(goto),线程恢复的功能。
java 虚拟机栈( Java Virtual Machine Stacks)
java虚拟机栈也是线程私有的,即一个线程会有一个虚拟机栈,其描述的是java虚拟机需要执行的方法。为每一个方法都创建了一个栈(stack fream),其包含了, 局部变量表、 操作数栈、 动态链接、 方法出口,等信息。 每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出,栈的过程。其中局部变量表存放了,各种基本类型数据,以及引用类型数据的地址(指针,代表一个对象的句柄,一条字节码指令的地址),后面会详细解释java虚拟机栈内的具体信息。
对这个区域规定了两种异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈可以动态扩展(当前大部分的Java虚拟机都可动态扩展,只不过Java虚拟机规范中也允许固定长度的虚拟机栈),如果扩展时无法申请到足够的内存,就会抛出outOfMemoryError异常
本地方法栈( Native Method Stack)
为什么要有本地方法?
java 有的时候需要和外系统进行交互,如果外系统不是使用java进行实现的话,就很难进行交互,java有的时候还需要和系统底层的一些硬件打交道,所以就出现了本地方法栈。
本地方法如何定义?
简单地讲,一个Native Method就是一个java调用非java代码的接口。一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C。这个特征并非java所特有,很多其它的编程语言都有这一机制,比如在C++中,你可以用extern "C"告知C++编译器去调用一个C的函数。
   "A native method is a Java method whose implementation is provided by non-java code."
   在定义一个native method时,并不提供实现体(有些像定义一个java interface),因为其实现体是由非java语言在外面实现的。下面给了一个示例:    
    public class IHaveNatives
    {
      native public void Native1( int x ) ;
      native static public long Native2() ;
      native synchronized private float Native3( Object o ) ;
      native void Native4( int[] ary ) throws Exception ;
    } 
其实本地方法栈的功能和虚拟机栈的功能类似,同事也是线程私有,也是存储当前执行的所有方法和函数执行的信息。同样本地方法栈也会抛出StackOverflowError和outOfMemoryError异常信息。
Java堆(Java Heap)
java堆是内存当中最大的一块,里面存储了对象的信息,被所有线程所共享的一片内存区域。在虚拟机规范当中是这样定义的: 所有的对象实例以及数组都要在堆上分配,但是随着JIT编译器的发展与逃逸分析技术逐渐成熟,栈上分配、 标量替换优化技术将会导致一些微妙的变化发生,所有的对象都
分配在堆上也渐渐变得不是那么“绝对”了。
GC操作就发生在这个区域,主要分成新生代和老生代,如果再详细划分, Eden空间、 From Survivor空间、 To Survivor空间等。在这个线程共享的区域,可能会划分出线程的缓冲区,不过再怎么去进行划分,都是为了能够管理这个空间,做好垃圾的回收工作。
根据Java虚拟机规范的规定,Java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可,就像我们的磁盘空间一样。 在实现时,既可以实现成固定大小的,也可以是可扩展的,不过当前主流的虚拟机都是按照可扩展来实现的(通过-Xmx和-Xms控制)。 如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。
方法区(Method Area)
方法区是线程共享的一段区域, 它用于存储已被虚拟机加载的类信息、 常量、 静态变量、 即时编译器编译后的代码等数据。
 
通过自己的理解我把图化成了如下的样子

欢迎关注我的微信公众号 “我是一个假的程序猿”

分享生活,技术,程序猿养生(我是认真的),以及程序猿招聘(欢迎程序猿关注),HR招聘信息发送(欢迎HR投稿)。

 

转载于:https://www.cnblogs.com/binarysheep/p/9479698.html

相关文章:

  • 对CRC32的小结加上bugku一道题目:好多压缩包
  • Excel-DNA自定义函数的参数智能提示功能:ExcelDna.IntelliSense1.1.0.rar
  • D05——C语言基础学PYTHON
  • 常见HTTP状态码
  • 蓝牙学习(4) -- L2CAP
  • c#窗体项目:工艺注意事项
  • Linux 常用命令——文件处理命令
  • python 爬虫 5i5j房屋信息 获取并存储到数据库
  • HDU - 2255 奔小康赚大钱 KM算法 模板题
  • LDAP概念和原理
  • Leetcode 118 杨辉三角
  • 如何搭建lamp(CentOS7+Apache+MySQL+PHP)环境
  • 安装vmtools
  • vue基础代码
  • POJ 2516 Minimum Cost 【费用流】
  • bootstrap创建登录注册页面
  • canvas 高仿 Apple Watch 表盘
  • css布局,左右固定中间自适应实现
  • Docker容器管理
  • ES6简单总结(搭配简单的讲解和小案例)
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • java取消线程实例
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • mysql innodb 索引使用指南
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • PHP面试之三:MySQL数据库
  • react-native 安卓真机环境搭建
  • scala基础语法(二)
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 前端知识点整理(待续)
  • 区块链技术特点之去中心化特性
  • 使用 QuickBI 搭建酷炫可视化分析
  • 使用docker-compose进行多节点部署
  • 问题之ssh中Host key verification failed的解决
  • 我感觉这是史上最牛的防sql注入方法类
  • 系统认识JavaScript正则表达式
  • 一个项目push到多个远程Git仓库
  • elasticsearch-head插件安装
  • # Panda3d 碰撞检测系统介绍
  • # 计算机视觉入门
  • #Spring-boot高级
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • (4) PIVOT 和 UPIVOT 的使用
  • (42)STM32——LCD显示屏实验笔记
  • (二)hibernate配置管理
  • (附源码)springboot教学评价 毕业设计 641310
  • (四)鸿鹄云架构一服务注册中心
  • (转)可以带来幸福的一本书
  • (转)用.Net的File控件上传文件的解决方案
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .NET CORE Aws S3 使用
  • .Net 代码性能 - (1)
  • .net 反编译_.net反编译的相关问题
  • .NET框架设计—常被忽视的C#设计技巧
  • :not(:first-child)和:not(:last-child)的用法