Java运行时内存区域

  Java虚拟机在运行Java程序的时候会将它所管理的内存区域划分为多个不同的区域。每个区域都有自己的用途,创建以及销毁的时间。有的随着虚拟机的启动而存在,有的则是依赖用户线程来启动和销毁。

  1. 程序计数器

     程序计数器是一块很小的区域,可以看做是用来表示线程所执行到字节码的某一行的行号指示器。

     在Java虚拟机中,多线程是线程之间轮流切换并分配处理器的执行时间来实现的,为了线程切换之后能够继续回到之前的代码行继续执行,所以每个线程都有一个“线程私有”的程序计数器。

     如果线程正在执行的是一个Java方法,则计数器记录的就是正在执行的虚拟机字节码指令的地址。如果正在执行的是一个Native方法,则这个计数器为空。

  2. Java虚拟机栈

     Java虚拟机栈也是线程私有的,生命周期与线程相同。

     每个方法在被执行的时候都会创建一个栈帧,用于存储局部变量表、操作栈、动态链接、方法出口等信息。

     每一个方法在被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

  3. 本地方法栈

     本地方法栈与虚拟机栈类似的,虚拟机栈为虚拟机执行Java方法服务,本地方法栈为虚拟机使用到的Native方法服务。

     Sun HotSpot虚拟机就直接将本地方法栈和虚拟机栈合二为一。

  4. Java堆

     Java堆(Java Heap)是Java虚拟机所管理的内存中最大的一块。

     Java堆是被所有的线程共享的一块区域,在虚拟机启动时候创建。此区域的作用就是存放对象实例。

    Java堆还可以细分为:新生代和老年代。不论如何划分,存放的依然是对象,划分的目的是为了更快的回收内存或者分配内存。

  5. 方法区

     方法区(Method Area)与Java堆一样,是各个线程共享的内存区域。

     方法区中用于存储已经被虚拟机加载的类的信息、常量、静态变量、即时编译后的代码等数据。

    虚拟机垃圾收集行为在这个区域很少出现,在这个区域的内存回收目标主要是对常量池的回收和对类型的卸载。

    • 运行时常量池

       运行时常量池是方法区的一部分。Class类中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译期生成各种字面量和符号引用,这部分内容会在类加载之后存放到运行时常量池中。

       运行时常量池相较于Class文件常量池的一个重要特征是具备动态性。常量并不一定是只在编译期产生,运行期间也可以将新的常量放入到池中,比如String类的intern()方法。

直接内存

   直接内存并不是虚拟机运行时数据区域的一部分。直接内存是在Java加入了NIO之后出现的,NIO引入了一种基于信道(Channel)与缓冲区(Buffer)的I/O方式,它可以食用Native函数库直接分配堆外内存,然后通过存放在Java堆里的一个DirectByteBuffer对象作为这块内存的引用进行操作。

对象访问

   对于Object obj = new Object();来说

   Object obj将会反应到Java栈的本地变量表中,作为一个reference类型的数据出现。而new Object()这部分就会反应到Java堆中,形成一块存储了Object类型所有实例数据值的结构化内存。在Java堆中还必须包含能查到此对象类型数据(如对象类型、父类、实现的接口、方法等)的地址信息,这些类型数据则存储在方法区中。

   在Java虚拟机规范中reference类型是指向对象的一个引用,不同的虚拟机实现的对象的引用方式不同,主流的访问方式有两种:使用句柄和直接指针。

    • 使用句柄   

       Java堆中会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象的实例数据和类型数据各自的具体地址信息。

    • 直接指针

      使用直接指针的访问方式,reference中存放的就直接是对象的地址。

  两种访问方式优缺点:

    使用句柄访问方式的最大好处就是reference中存放的是稳定的句柄地址,在对象被移动(垃圾收集时移动对象时非常普遍的行为)时只需要修改句柄中的实例数据指针,而reference本身不用修改。

    使用直接指针访问方式的最大好处就是速度更快,它节省了中间一次指针定位的时间开销,对象的访问在Java中非常频繁,这类开销积少成多也是非常可观的执行成本。

    各个厂商的虚拟机不同,Sun HotSpot虚拟机采用的是直接指针访问方式进行对象的访问。

<<深入Java虚拟机>>-第二章-Java内存区域-学习笔记的更多相关文章

  1. 虚拟机--第二章java内存区域与内存溢出异常--(抄书)

    这是本人阅读周志明老师的<深入理解Java虚拟机>第二版抄写的,有很多省略,不适合直接阅读,需要阅读请出门左转淘宝,右转京东,支持周老师(侵权请联系删除) 第二章java内存区域与内存溢出 ...

  2. 深入理解java虚拟机-第二章:java内存区域与内存泄露异常

    2.1概述: java将内存的管理(主要是回收工作),交由jvm管理,确实很省事,但是一点jvm因内存出现问题,排查起来将会很困难,为了能够成为独当一面的大牛呢,自然要了解vm是怎么去使用内存的. 2 ...

  3. 深入理解java虚拟机(1)------内存区域与内存溢出

    在C++领域,关于C++的内存存储,结构等等,有一本书:深度探索C++对象模型,讲解的非常透彻. 而Java确把这一工作交给了虚拟机来处理. 我们首先来看看关于内存的问题. 1.问题: 1)java ...

  4. Java虚拟机(JVM)内存区域

            Java虚拟机内存区域分为五部分:程序计数器.Java虚拟机栈.本地方法栈.堆.方法区.其中程序计数器.Java虚拟机栈.本地方法栈属于线程私有内存区,其生命周期与线程相同,随线程的产 ...

  5. 深入理解java虚拟机-第二章

    第2章 Java内存区域与内存溢出异常 运行数据区域 1.程序计数器(Program Counter Register) 是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器. 2.J ...

  6. 2016021801 - Java内存区域学习笔记

    根据<深入理解java虚拟机>学习归纳整理学习笔记 程序计数器 用途:当前线程的字节码文件的行号指示器.(当前机场负责控制飞机降落的空管员:当前线程表示当前机场, 所执行的字节码等同于被等 ...

  7. JAVA基础第二章-java三大特性:封装、继承、多态

    业内经常说的一句话是不要重复造轮子,但是有时候,只有自己造一个轮子了,才会深刻明白什么样的轮子适合山路,什么样的轮子适合平地! 我将会持续更新java基础知识,欢迎关注. 往期章节: JAVA基础第一 ...

  8. java入门第二章——java编程基础

    习题 一.填空题 (p)1.java中的程序代码都必须在一个类中定义,类使用(class)关键字来定义. (p)2.布尔常量即布尔类型的两个值,分别是(true)和(false) (p18)3.jav ...

  9. ASP.NET本质论第二章应用程序对象学习笔记1

    1.请求的处理参数—上下文对象HttpContext 1) 针对每一次请求,ASP.NET将创建一个处理这次请求所使用的HttpContext对象实例,这个对象实例将用来在ASP.NET服务器的处理过 ...

随机推荐

  1. 设置UITabBarController的背景颜色

    if (IOS7) { self.tabBarController.tabBar.barTintColor = kTAB_BAR_GB_COLOR; }else{ self.tabBarControl ...

  2. Microsoft.AspNet.FriendlyUrls发布到IIS后404报错的解决方案

    我一个项目都基本上做完了,结果部署到我服务器的时候结果一直报404 找不到 一看global.asax有个路由注册的代码 public static void RegisterRoutes(Route ...

  3. JS 数据类型转换-转换函数、强制类型转换、利用js变量弱类型转换

    1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把值转换成浮点数.只有对String类型调用这些方法,这两个函数才能正确运行:对其他类型 ...

  4. Mac联网恢复系统重新安装Lion

    Mac的Lion系统,虽然不像Windows那样需要经常重装,但也难免会有要重置的时候,比如更换硬盘.本文介绍如何利用Mac的联网恢复系统进行Lion系统的在线恢复.Mac的在线恢复系统只在近几年的机 ...

  5. Tomcat 生产服务器性能优化

    虑一下这种场景,你开发了一个应用,它有十分优秀的布局设计,最新的特性以及其它的优秀特点.但是在性能这方面欠缺,不管这个应用如何都会遭到客户拒绝.客户总是期望它们的应用应该有更好的性能.如果你在产品中使 ...

  6. SpiderMonkey-让你的C++程序支持JavaScript脚本

    译序 有些网友对为什么D2JSP能执行JavaScript脚本程序感到奇怪,因此我翻译了这篇文章,原文在这里.这篇教程手把手教你怎样利用SpiderMonkey创建一个能执行JavaScript脚本的 ...

  7. skip-character-set-client-handshake 与 character-set-client-handshake

    my.cnf [mysql] default-character-set = gbk [mysqld] skip-character-set-client-handshake=1 跳过mysql程序起 ...

  8. careercup-中等难度 17.9

    17.9 设计一个方法,找出任意指定单词在一本书中的出现频率. 解法: 1 单次查询 遍历这本书的每个单词,计算给定单词出现的次数.时间复杂度O(n),我们无法继续优化它,因为书中的每个单次都需要访问 ...

  9. 信号之sigsetjmp和siglongjmp函数

    在信号处理程序中经常调用longjmp函数以返回到程序的主循环中,而不是从该处理程序返回. 但是,调用longjmp有一个问题.当捕捉到一个信号时,进入信号捕捉函数,此时当前信号被自动地加到进程的信号 ...

  10. mysql distinct跟group by性能

    mysql distinct和group by性能   1,测试前的准备 //准备一张测试表 mysql> CREATE TABLE `test_test` ( ->   `id` int ...