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. Quartz.Net源码Example之Quartz.Examples.AspNetCore

    Quartz.Examples.AspNetCore ​ .NetCore的Web系统,后台主要执行多个触发器任务,前台展示所有触发器信息和正在执行的作业的相关信息,还可以通过访问health-UI来 ...

  2. 【分析笔记】展讯 RDA8810PL 平台 Camera 驱动分析和移植(Android 4.4 )

    前言概述 因以下原因,导致不得不通过代码分析来学习如何在该平台下进行摄像头驱动移植 香橙派开发商(迅龙软件)仅提供能跑起来的源代码.固件,以及简单的编译文档,不提供其它技术支持 baidu.googl ...

  3. .Net 7 高端玩法,自定义一个CLR运行时

    前言: 曾几何时,一直想自己定制一个CLR运行时玩玩.满足下技术控的虚荣心,本篇带你一步一步打造一个属于自己的.Net 7运行时. 概括 假设你的电脑已经安装了.Net,并且运行正常.在进行自定义运行 ...

  4. immutable.js学习笔记(六)----- OrderedSet

    一.OrderedSet 二.普通Set 与 OrderedSet 注意:普通Set并不是严格的一定是升序的 三.takeWhile 四.升序 sort valueA - valueB 五.降序 va ...

  5. docker命令之docker build

    docker命令之docker build 明天要讲docker file的公开课,正好借此机会,整理下docker 命令的专题 语法 docker build [OPTIONS] PATH | UR ...

  6. [​DuckDB] 多核算子并行的源码解析

    DuckDB 是近年来颇受关注的OLAP数据库,号称是OLAP领域的SQLite,以精巧简单,性能优异而著称.笔者前段时间在调研Doris的Pipeline的算子并行方案,而DuckDB基于论文< ...

  7. Opengl ES之踩坑记

    前因 最近在尝试使用Opengl ES实现一些LUT滤镜效果,在实现这些滤镜效果的时候遇到一些兼容性的坑,踩过这些坑后我希望把这几个坑分享给读者朋友们, 希望同在学习Opengl ES的朋友们能少走弯 ...

  8. 上午小博(java小知识)

    使用super来引用父类的成分,使用this来引用当前对象 一个类从另一个类继承,new这个子类的实例的时候,使用super来引用父类对象,this是指当前对象的引用. 当new一个对象出来的时候,这 ...

  9. java基础(完整版)

    java javaSE 注释: block块级 line 行 标识符和关键字 组成部分.变量名.类名.方法名--------标识符 $\数字._\字母 数据类型 强类型语言---安全性高--速度会慢 ...

  10. C语言补漏--内存管理-完结

    1.内存分布 2.内存操作函数 数组清空 2. 内存拷贝函数 数组拷贝 3.内存对比 总结 堆区开辟 内存泄漏只申请不释放,导致内存空间持续增长,导致推出 内存污染向没有申请的内存空间写数据  向堆区 ...