Java内存区域

在执行java程序的过程中JVM会把它管理的内存划分为多个不同的数据区域。 根据《Java 虚拟机规范 SE7版》的规定,Java 虚拟机所管理的内存将会包括以下几个运行时数据区域.

程序计数器

较小的一块内存区域,可以看作是当前线程所执行的字节码的行号指示器,在我们运行java程序的时,jvm 通过它来获取下一步的执行逻辑 也就是字节码解释器。 字节码解释器通过update这个计数器的值来选取下一条需要执行的字节码指令。 想象一下我们多线程执行的代码,每个线程执行的代码步骤 或者 说当前线程需要执行的下一步指令,jvm如何知道? 我们都知道多线程中一般都是有一个Main Thread 和 More sub Thread  大多数线程都是这样,从Main Thread 来启动一些sub Thread 。 每个线程因为获取CPU的时钟的不确定性,执行多久等等因数,jvm通过维护线程自身的程序计数器获取每个指令,每个线程都有自己的私有内存区域和计数器,从而jvm通过它来获取next。

虚拟机栈 

虚拟机栈描述的是Java方法执行的内存模型: 每个方法在执行的时候都会创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每一个方法从调用知道执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。 局部变量表,是用来存入编译期可知的各种基础数据类型、对象的引用类型和returnAddress(指向了一条字节码指令的地址)。 局部变量表的内存空间在编译期间完成分配,在方法运行期间不会改变局部变量表的大小,因为在编译期间每个类型的数据大小是固定的,除了long 和 double类型占用两个局部变量空间外,其他都只是一个空间。

本地方法栈

他与虚拟机栈的作用非常相似,他们之间的区别,本地方法栈为虚拟机使用到了Native方法服务,虚拟机栈是为java程序的方法服务。因为本地方法栈中使用的语言,使用的方式与数据结构并没有强制规定,因为每种虚拟机可以自由的实现它。其实有一个疑问,多线程中如果有调用Native方法,native方法是否是线程安全的,如果是线程安全的,那么jvm是在线程自己的内存区域有一个本地方法栈吗? 如果不是线程安全,那么他们直接每次都直接调用主线程的本地方法栈,是否需要而外的同步呢?待请教过大神后来解释....(大神也不是很确定,但是他也说了,一般我们线程问题都是因为存在访问共享内存,native方法你完全不知道他的具体实现,又怎么可以获取到他的变量信息呢? )

转载自 http://hi.baidu.com/holder/item/e71e50a87389da9f151073e0, 以下是其中一段:

对于一个运行中的Java程序而言,它还可能会用到一些跟本地方法相关的数据区。当某个线程调用一个本地方法时,它就进入了一个全新的并且不再受虚拟机限制的世界。本地方法可以通过本地方法接口来访问虚拟机的运行时数据区,但不止于此,它还可以做任何它想做的事情。比如它甚至可以直接使用本地处理器中的寄存器,或者直接从本地内存的堆中分配任意数量的内存等等。总之,它和虚拟机拥有同样的权限(或者说能力)。

本地方法本质上是依赖于实现的,虚拟机实现的设计者们可以自由地决定使用怎样的机制来让Java程序调用本地方法。

任何本地方法接口都会使用某种本地方法栈。当线程调用Java方法时,虚拟机会创建一个新的栈帧并压入Java栈。然而当它调用的是本地方法时,虚拟机会保持Java栈不变,不再在线程的Java栈中压入新的帧,虚拟机只是简单地动态链接并直接调用指定的本地方法。可以把这看作是虚拟机利用本地方法来动态扩展自己。就如共Java虚拟机是的实现在按照其中运行的Java程序的吩咐,调用属于虚拟机内部的另一(动态链接的)方法。

如果某个虚拟机实现的本地方法接口是使用C连接模型的话,那么它的本地方法栈就是C栈。我们知道,当C程序调用一个C函数时,其栈操作都是确定的。传递给该函数的参数以某个确定的顺序压入栈,它的返回值也以确定的方式传回调用者。同样,这就是该虚拟机实现中本地方法栈的行为。

很可能本地方法接口需要回调Java虚拟机中的Java方法(这也是由设计者决定的),在这种情形下,该线程会保存本地方法栈的状态并进入到另一个Java栈........

jvm规范中描述的是:所有的对象示例以及数组都要在堆上分配,但是随着JIT编译器的发展和逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化,所有的对象都分配在堆上也渐渐变得不是那么“绝对”了。垃圾收集器管理的主要区域就是堆了,从内存回收的角度上,由于现在收集器基本上采用分代收集算法,所以java堆还可以分为:新生代和老年代。

很多人都愿意把方法区叫做永久代,本质上两者并不相等,仅仅是因为HotSopt虚拟机的设计团队选择把GC分代收集扩展至方法区,或者说使用永久代来实现方法区而已,这样HotSopt的垃圾收集器可以像管理Java堆一样管理这部分内存,能够省去专门为方法区编写的内存管理代码工作。 原则上,如何实现方法区属于虚拟机的实现细节,但使用永久代来实现方法区,现在看来更容易遇到内存溢出的问题。

运行时常量池

他是方法区的一部分,Class文件中除了类的版本,字段,方法,接口等描述信息外,还有一项信息是常量池,用于存放编译期生成的各种字面量和符号引用。

深入理解JVM 学习笔记2的更多相关文章

  1. java jvm学习笔记七(jar包的代码认证和签名)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 前言: 如果你循序渐进的看到这里,那么说明你的毅力提高了,jvm的很多东西都是比较抽像的,如果不找相对应的代码来辅助理解 ...

  2. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  3. java之jvm学习笔记三(Class文件检验器)

    java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...

  4. java之jvm学习笔记四(安全管理器)

    java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...

  5. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  6. java之jvm学习笔记十三(jvm基本结构)

    java之jvm学习笔记十三(jvm基本结构) 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让概念在你的脑子里变成 ...

  7. JVM学习笔记-JVM模型

    JVM学习笔记 == 标签(空格分隔): jvm 学习笔记全部来自于<深入理解java虚拟机>总结 jvm内存示意图 虚拟机栈(Java Virtual Machine Stacks): ...

  8. JVM学习笔记——内存结构篇

    JVM学习笔记--内存结构篇 在本系列内容中我们会对JVM做一个系统的学习,本片将会介绍JVM的内存结构部分 我们会分为以下几部分进行介绍: JVM整体介绍 程序计数器 虚拟机栈 本地方法栈 堆 方法 ...

  9. JVM学习笔记:虚拟机的类加载机制

    JVM类加载机制分两部分来总结: (1)类加载过程 (2)类加载器 一.JVM类加载过程 类的加载过程:加载 →连接(验证 → 准备 → 解析)→ 初始化. 类的生命周期:加载 →连接(验证 → 准备 ...

  10. JVM学习笔记:字节码执行引擎

    JVM学习笔记:字节码执行引擎 移步大神贴:http://rednaxelafx.iteye.com/blog/492667  

随机推荐

  1. 线上排查:内存异常使用导致full gc频繁

    线上排查:内存异常使用导致full gc频繁 问题系统 日常巡检发现,应用线上出现频繁full gc 现象 应用线上出现频繁full gc 排查过程 分析dump 拉dump文件:小插曲:dump时如 ...

  2. 前端(vue)导出pdf

    纯前端导出 pdf 实现方法如下: 1. 安装 html2pdf.jspdf npm install html2canvas jspdf --save 2. 项目 utils 文件夹中新建一个 htm ...

  3. 调用HttpClient.PostAsync时传token等值

    做内部接口转发时加token验证需要传token值过去,有如下两种方式 string jsonContent = JsonConvert.SerializeObject(args); using(va ...

  4. Spring Cloud Openfeign Get请求发生405错误

    kust-retrieve服务 @Resource private AuthFeignService authFeignService; @ApiOperation("获取用户信息" ...

  5. ElasticSearch7.6入门

    笔记记录 B站狂神说Java的ElasticSearch课程:https://www.bilibili.com/video/BV17a4y1x7zq 一.ElasticSearch概述 官网:http ...

  6. 了解舵机以及MG996R的控制方法

    了解舵机以及MG996R的控制方法 1.舵机基础知识: 舵机是遥控航空.航天模型控制动作,改变方向的重要组成部件,舵机是一种位置(角度)伺服的驱动器. 舵机主要适用于那些需要角度不断变化并可以保持的控 ...

  7. python之路76 路飞项目 企业项目类型、软件开发流程、路飞项目需求、pip永久换源、虚拟环境、路飞项目前后端创建、包导入、后端项目目录调整

    知识获取渠道 cnblogs csdn 掘金 思否 找工作app boss直骗.拉钩.智联.猎聘.脉脉(内推,hr). 企业项目类型 1.面向互联网用户:商城类项目 微信小程序商城 2.面向互联网用户 ...

  8. 跳板攻击之:Socks 代理转发

    跳板攻击之:Socks 代理转发 目录 跳板攻击之:Socks 代理转发 1 Socks 代理转发原理 2 实验环境 2.1 客户端配置 2.2 服务端配置 2.3 利用 Socks 代理扫描内网主机 ...

  9. win11 文件夹内关闭显示更多

    使用命令提示符 打开cmd窗口,输入  reg add HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\Inpro ...

  10. PostGIS之Geometry

    1. 概述 PostGIS 是PostgreSQL数据库一个空间数据库扩展,它添加了对地理对象的支持,允许在 SQL 中运行空间查询 PostGIS官网:About PostGIS | PostGIS ...