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. 互斥锁、线程理论、GIL全局解释器、信号量、event事件、进程池和线程池以及协程

    目录 一.互斥锁代码实操 1.互斥锁的概念 2.互斥锁的使用 3.死锁现象 4. 小结 二.线程理论 进程 线程 线程简介 为什么要使用多线程? 多线程概念 多进程的优点: 线程与进程的区别 线程的特 ...

  2. 视觉十四讲:第七讲_ORB特征点

    1.特征点 特征点是图像里一些特别的地方,如角点.边缘和区块.比较著名有SIFT.SURF.ORB等.SIFT充分考虑了图像变换过程中出现的光照.尺度.旋转等变换,但是计算量非常大.而ORB是质量和性 ...

  3. STM32F0库函数初始化系列:ADC

    static void ADC_Config(void) { ADC_InitTypeDef ADC_InitStructure; /* ADCs DeInit */ //ADC_DeInit(ADC ...

  4. RocketMQ - 生产者启动流程

    生产者启动流程 DefaultMQProducer是RocketMQ中默认的生产者实现 核心属性: namesrvAddr: 继承自 ClientConfig,表示 RocketMQ 集群的Names ...

  5. JZOJ 3207.Orthogonal Anagram

    \(\text{Problem}\) 给出一个字符串,求经过重新排列的另一个字典序最小的字符串,满足:相同的位置上 原串与结果串的字符不同.不存在则输出空串. \(\text{Solution}\) ...

  6. 在wifi的5G频率下无法加载图片解决方法

    开始是这样的:因为我家wifi支持300兆的网速,所以换了一个荣耀的路由器,换了一根网线,但是发现5G频率有的应用加载不了图片,所以查了很多资料想了很多办法,终于解决了, 解决方法如下: 1.这是DH ...

  7. 常见数据库mysql、oracle和DB2中is null 和 =null 的区别

    问题背景:前段时间我在测试过程中上传一个文件,文件内容要求判断为空,结果出现了报错,跟踪原因发现是开发误将oracle中对null的判断方式写成了=null,下面梳理一下不同数据库对该问题的处理方法: ...

  8. Django中获取用户IP方法

    Django中通过request.META可以来获取用户的IP. request.META 是一个Python字典,包含了所有本次HTTP请求的Header信息,比如用户IP地址和用户Agent(通常 ...

  9. 【转载】docker swarm集群中部署traefik和其他服务

    以下配置来自:https://blog.csdn.net/wave_sheep/article/details/104186192 感谢作者! traefik.yaml version: '3' se ...

  10. mysql explain 查看sql语句执行计划概述

    mysql explain 查看sql语句执行计划概述 id:选择标识符select_type:表示查询的类型.table:输出结果集的表partitions:匹配的分区type:表示表的连接类型po ...