一 Java内存区域与HotSpot虚拟机对象
1 Java技术体系、JDK、JRE?
    Java技术体系包括:
        · Java程序设计语言;
        · 各种硬件平台上的Java虚拟机;
        · Class文件格式;
        · Java API类库;
        · 来自商业机构或开源社区的第三方Java类库。
    JDK,即Java开发工具包,包括Java程序设计语言、Java虚拟机、Java API类库,是用于支持Java程序开发的最小环境;不仅提供了Java程序运行所需要的JRE,还提供了一系列的编译、调试工具,如javac、jconsole等。
    JRE,即Java运行时环境,包括Java API类库中的Java SE API子集和Java虚拟机两部分,是用于支持Java程序运行的标准环境。
 
2 Java内存区域如何划分?
    Java内存区域分为五部分:程序计数器、虚拟机栈、本地方法栈、方法区、堆。
    (1)程序计数器:
    ---当前线程所执行的字节码的行号指示。若线程正在执行的是一个java方法,则计数器记录的是正在执行的虚拟机字节码指令;若线程正在执行的是一个Native方法(本地方法),则计数器值为空;
    ---线程私有的;
    ---唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。
    (2)虚拟机栈:
    ---描述的是Java方法执行的内存模型:每个方法在执行时都会创建一个栈帧用于存储局部变量、操作数栈、动态链接、方法出口等信息;每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
    ---线程私有的,生命周期与线程相同;
    ---使用连续的内存空间;
    ---两种异常:若线程请求的栈深度大于虚拟机所允许的深度,抛出StackOverflowError异常;若虚拟机栈可以动态扩展,当扩展时无法申请到足够的内存,抛出OutOfMemoryError异常。
    (3)本地方法栈:
    ---本地方法栈和虚拟机栈的唯一区别是虚拟机栈是为虚拟机执行java方法服务,而本地方法栈为虚拟机执行Native方法服务,其他与虚拟机栈一样。
    (4)Java堆:
    ---虚拟机启动时创建,用于存放对象实例,几乎所有的对象实例都在Java堆中分配内存(随着JIT编译器的发展和逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术可能导致对使得实例在栈上直接分配);
    ---所有线程共享的;
    ---是垃圾收集器管理的主要区域。从内存回收角度,可分为:新生代和老年代;从内存分配的角度,Java堆中可分出多个线程私有的分配缓冲区(TLAB)。
    ---可以处于物理上不连续的内存空间、可以选择固定大小或者可扩展。可能抛出OutOfMemoryError异常。
    (5)方法区:(HotSpot: 永久代)
    ---用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据;
    ---线程共享的;
    ---此区域内存回收的主要目标是常量池的回收和类型的卸载;
         ---不需要连续内存、可以选择固定大小或者可扩展、还可以选择不进行垃圾收集。当无法满足内存分配需求时,将抛出OutOfMemoryError异常。
 
3 运行时常量池
        ---运行时常量池是方法区的一部分;
        ---Class文件中的常量池用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放;
        ---Java虚拟机规范没有对运行时常量池做任何细节的要求,不同的提供商实现的虚拟机可以按照自己的需要来实现这个内存区域;
        ---具备动态性,运行期间也可能将新的常量放入池中,如String类的intern()方法。
 
4 对象的创建过程
    普通Java对象(不包括数组和Class对象)的创建过程为:
        (1)首先检查new指令的参数能否在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始化过,如果没有,则先执行相应的类加载过程。
        (2)在类加载检查通过后,虚拟机将为新生对象分配内存。
                分配方式有:
                    · “指针碰撞”:当Java堆中内存是绝对规整的,所有用过的内存放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器。此时,分配内存仅需要把那个指针向空闲空间那边挪动一段与对象大小相等的距离。
                    · “空闲列表”:当Java堆中的内存不是规整的,此时,虚拟机必须维护一个列表,记录上哪些内存块是可用的,分配的时候从列表中找到一块足够大的空间划分给对象实例,并且更新列表上的记录。
              选择哪种分配方式是由Java堆是否规整决定,而Java堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。因此,使用Serial、ParNew等带Compact过程的收集器时,系统采用的分配方式为指针碰撞;使用CMS这种基于标记-清除算法的收集器,系统采用的分配方式为空闲列表。
                分配内存的操作在并发情况下并不是线程安全的,解决方法有:
                    · 对分配内存空间的动作进行同步处理,而实际上虚拟机采用CAS配上失败重试的方式保证更新操作的原子性。
                    · 把内存分配的动作按照线程划分在不同的空间中进行,即每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(TLAB)。
        (3)虚拟机将分配到的内存空间都初始化为零值(不包括对象头)。
        (4)虚拟机对对象进行必要的设置,如这个对象是哪个类的实例、对象的哈希码、对象的GC分代年龄等。
        (5)一般来说,执行new指令之后还会接着执行<init>方法,把对象按照程序员的意愿进行初始化。
5 对象的内存布局
    对象在内存中存储的布局可分为3块区域:对象头、实例数据、对齐填充。
    对象头包括两部分:
        · 存储对象自身的运行时数据(Mark Word),如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。考虑到虚拟机的空间效率,Mark Word被设计成根据对象的状态复用自己的存储空间。
        · 类型指针,即对象指向它的类元数据的指针。若对象是一个Java数组,则还必须有一块用于记录数组长度的数据。
    实例数据:在程序代码中所定义的各种类型的字段内容,包括父类继承下来的和子类中所定义的。存储顺序受虚拟机分配策略参数和字段在Java源码中定义顺序的影响。规则:相同宽度的字段总是被分配到一起,在父类中定义的变量会出现在子类之前。
    对齐填充:起占位符的作用。对象的大小必须是8字节的整数倍。
6 对象的访问方式
    (1)使用句柄访问
            方式:Java堆中划分出一块内存作为句柄池,reference中存储的是对象的句柄地址,而句柄中包含了对象实例数据和类型数据各自的具体地址信息。
            优点:reference中存储的是稳定的句柄地址,对象被移动时只会改变句柄中的实例数据指针,reference本身不需要修改。

    (2)使用直接指针访问
            方式:reference中存储的是对象地址。
            优点:节省了一次指针定位的时间开销,速度更快。

 

深入理解Java虚拟机读书笔记1----Java内存区域与HotSpot虚拟机对象的更多相关文章

  1. 《Effective Java》读书笔记(一)之创建和销毁对象

    最近在研读<Effective Java>一书,读书不做点笔记,感觉很容易就忘掉,于是用本篇博客来记录阅读此书的笔记. 郑重声明: 由于是<Effective Java>一书的 ...

  2. 深入理解Java虚拟机 -- 读书笔记(1):JVM运行时数据区域

    深入理解Java虚拟机 -- 读书笔记:JVM运行时数据区域 本文转载:http://blog.csdn.net/jubincn/article/details/8607790 本系列为<深入理 ...

  3. 《深入理解 Java 虚拟机》读书笔记:Java 内存区域与内存溢出异常

    前言 最近开始看这本书,记得前段时间拿起这本书的时候,心情是相当沉重的!当时的剧本是这样的-- 内景.家里 - 下午 我(画外):唉,有点无聊啊!(偶然撇过书架)这么多书得看到什么时候啊,要不要拿一本 ...

  4. 深入理解Java虚拟机之读书笔记一 自动内存管理机制

    一.运行时数据区域 1.程序计数器是线程的私有空间,每个线程都有.针对线程执行的是Java代码还是Native代码有两种取值,Java代码时:虚拟机字节码指令的地址:Native代码时:计数值为Und ...

  5. 深入理解Java虚拟机——读书笔记

    首先 强烈推荐周志明老师的这本书,真的可以说是(起码中文出版界)新手了解Java虚拟机必须人手一本的教科书!!!   第二部分自动内存管理机制 由于Java虚拟机的多线程是通过线程轮流切换并分配处理器 ...

  6. 《深入java虚拟机》读书笔记之Java内存区域

    前言 该读书笔记用于记录在学习<深入理解Java虚拟机--JVM高级特性与最佳实践>一书中的一些重要知识点,对其中的部分内容进行归纳,主要是方便之后进行复习. 运行时数据区域 Java虚拟 ...

  7. Java并发读书笔记:线程安全与互斥同步

    目录 导致线程不安全的原因 什么是线程安全 不可变 绝对线程安全 相对线程安全 线程兼容 线程对立 互斥同步实现线程安全 synchronized内置锁 锁即对象 是否要释放锁 实现原理 啥是重进入? ...

  8. java effective 读书笔记

    java effective 读书笔记 []创建和销毁对象 静态工厂方法 就是“封装了底层 暴露出一个访问接口 ” 门面模式 多参数时 用构建器,就是用个内部类 再让内部类提供构造好的对象 枚举 si ...

  9. 读书笔记-浅析Java运行时数据区

    作为一个 Java 为主语言的程序员,我偶尔也需要 用 C/C++ 写程序,在使用时让我很烦恼的一件事情就是需要对 new 出来的对象进行 delete/free 操作,我老是担心忘了这件事情,从而导 ...

随机推荐

  1. 20165313 《网络对抗技术》 Kali安装

    一.目的要求 下载 安装 网络 共享 软件源 二.主要步骤 我主要是按照最新超详细虚拟机VMware安装Kali Linux 这个方法做的就没有步骤描述了. 安装结果图: 注意事项 安装过程中如果没有 ...

  2. 20164318 毛瀚逸 Exp4 恶意代码分析

    ---恢复内容开始--- 1 关键内容 系统运行监控 (1)使用计划任务,每隔一分钟记录自己的电脑有哪些程序在联网,连接的外部IP是哪里.运行一段时间并分析该文件,综述分析结果. (2)安装配置sys ...

  3. 谈一谈socket与java

    用java中socket实现socket聊天 1,      什么是socket Socket 是指网络套接字,什么是套接字呢?    这是网络上一种端对端的网络协议,端口就是进程号,socket在网 ...

  4. nodejs-- vuex中mapActions

    mapActions() 返回的是一个对象, 用了 ... 扩展符后,才可以放进一个对象里,和其他组件内定义的 method 在同一个 methods 对象. { methods: mapAction ...

  5. js转盘游戏

    1----- @-webkit-keyframes spin { 0%   { -webkit-transform: rotate(0deg); -ms-transform: rotate(0deg) ...

  6. Assembly Experiment3

    AIMS & PREPARATIONS of THIS EXPERIMENT: 1st point of this experiment: realize the programme t1.a ...

  7. 引擎设计跟踪(九.14.3) deferred shading 准备

    目前做的一些准备工作 1.depth prepass for forward shading. 做depth prepass的原因是为了完善渲染流程, 虽然架构上支持多个pass, 但实际上从来没有测 ...

  8. visual studio 2017 中默认无法开发 Android 8.0 及以上系统的解决方案

    一般默认比较旧有两个原因,系统版本过旧,Visual Studio 版本过旧. 第一步,将windows 更新到最新版,必须是windows 10 并且更新到最新. 第二步,将visual studi ...

  9. LEB128相关知识

    LEB128相关知识 介绍 LEB128(little endian base 128)是一种变长的整数压缩编码形式,它是出自于DWARF debug file format.在Android的Dal ...

  10. MySQL 设置root密码报错:mysqladmin: connect to server at 'localhost' failed

    MySQL 设置root密码报错:mysqladmin: connect to server at 'localhost' failed 1.安装完MySQL设置root密码报错如下 [root@vm ...