深入理解JVM 学习笔记2
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的更多相关文章
- java jvm学习笔记七(jar包的代码认证和签名)
欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 前言: 如果你循序渐进的看到这里,那么说明你的毅力提高了,jvm的很多东西都是比较抽像的,如果不找相对应的代码来辅助理解 ...
- java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)
java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...
- java之jvm学习笔记三(Class文件检验器)
java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...
- java之jvm学习笔记四(安全管理器)
java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...
- java之jvm学习笔记二(类装载器的体系结构)
java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...
- java之jvm学习笔记十三(jvm基本结构)
java之jvm学习笔记十三(jvm基本结构) 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让概念在你的脑子里变成 ...
- JVM学习笔记-JVM模型
JVM学习笔记 == 标签(空格分隔): jvm 学习笔记全部来自于<深入理解java虚拟机>总结 jvm内存示意图 虚拟机栈(Java Virtual Machine Stacks): ...
- JVM学习笔记——内存结构篇
JVM学习笔记--内存结构篇 在本系列内容中我们会对JVM做一个系统的学习,本片将会介绍JVM的内存结构部分 我们会分为以下几部分进行介绍: JVM整体介绍 程序计数器 虚拟机栈 本地方法栈 堆 方法 ...
- JVM学习笔记:虚拟机的类加载机制
JVM类加载机制分两部分来总结: (1)类加载过程 (2)类加载器 一.JVM类加载过程 类的加载过程:加载 →连接(验证 → 准备 → 解析)→ 初始化. 类的生命周期:加载 →连接(验证 → 准备 ...
- JVM学习笔记:字节码执行引擎
JVM学习笔记:字节码执行引擎 移步大神贴:http://rednaxelafx.iteye.com/blog/492667
随机推荐
- 2023年 .NET Monorepo 来了
Monorepo(monolithic repository)是一种项目架构,简单来说就是,将多个项目或包文件放到一个git仓库来管理,很多前端项目vue3.element都是采用的这种架构模式. 之 ...
- uni-app + .NET 7实现微信小程序订阅消息推送
微信小程序的订阅消息是小程序的重要能力之一,为实现服务的闭环提供更优的体验.订阅消息我们应该经常见到,比如下单成功之后的服务通知,支付成功后的支付成功通知,都属于小程序的订阅消息. 本文只实现一次性订 ...
- RocketMQ Streams 1.1.0: 轻量级流处理再出发
本文作者:倪泽,Apache RocketMQ committer.RSQLDB/RocketMQ Streams Maintainer 01 背景 RocketMQ Streams是一款基于Rock ...
- 文本纠错:提升OCR任务准确率的方法理解
文本纠错:提升OCR任务准确率的方法理解 摘要:错字率是OCR任务中的重要指标,文本纠错需要机器具备人类水平相当的语言理解能力.随着人工智能应用的成熟,越来越多的纠错方法被提出. 近年来深度学习在O ...
- SqlServer Express 自动备份数据库(没有sql代理服务的情况下)
一.由于Express版本的SQLServer没有SQL代理服务(SQLSERVERAGENT),所以就不能通过SQLServer作业来进行自动备份了,那么我们可以用Windows计划任务来定时处理 ...
- 源码下载teb
git clone https://github.com/rst-tu-dortmund/teb_local_planner.git git checkout <ros版本分支> git ...
- Linux服务器数据备份恢复
转载csdn: https://blog.csdn.net/weixin_33794672/article/details/92894022
- 如何获取win10用户最高权限
第五步,在(输入对象名称)方框中输入"System Managed Accounts Group",再点击"检查名称" 转载: 百度经验: https: ...
- Eureka高可用集群服务端和客户端配置
微服务应用中,生产环境一般都需要保障服务注册中心的高可用!高可用也分好几个等级,例如:同数据中心(可用Zone区)高可用-->同地域(Region)跨数据中心(可用Zone区)高可用--> ...
- 为什么不建议使用 @Autowired 注解进行注入
在Spring中,Bean的注入一般有三种方式:属性注入.set方法注入.构造器注入. 1.Autowired注入的原理 @Autowired属于属性注入,默认按照类型装配,默认情况下要求依赖的对象必 ...