摘自:http://blog.csdn.net/woaigaolaoshi/article/details/51439227

在HotSpot中,对象的类型信息里有记录自己的OopMap,记录了在该类型的对象内什么偏移量上是什么类型的数据。所以从对象开始向外的扫描可以是准确的;这些数据是在类加载过程中计算得到的。

可以把oopMap简单理解成是调试信息。 在源代码里面每个变量都是有类型的,但是编译之后的代码就只有变量在栈上的位置了。oopMap就是一个附加的信息,告诉你栈上哪个位置本来是个什么东西。 这个信息是在JIT编译时跟机器码一起产生的。因为只有编译器知道源代码跟产生的代码的对应关系。 每个方法可能会有好几个oopMap,就是根据safepoint把一个方法的代码分成几段,每一段代码一个oopMap,作用域自然也仅限于这一段代码。 循环中引用多个对象,肯定会有多个变量,编译后占据栈上的多个位置。那这段代码的oopMap就会包含多条记录。

每个被JIT编译过后的方法也会在一些特定的位置记录下OopMap,记录了执行到该方法的某条指令的时候,栈上和寄存器里哪些位置是引用。这样GC在扫描栈的时候就会查询这些OopMap就知道哪里是引用了。这些特定的位置主要在: 
1、循环的末尾 
2、方法临返回前 / 调用方法的call指令后 
3、可能抛异常的位置

这种位置被称为“安全点”(safepoint)。之所以要选择一些特定的位置来记录OopMap,是因为如果对每条指令(的位置)都记录OopMap的话,这些记录就会比较大,那么空间开销会显得不值得。选用一些比较关键的点来记录就能有效的缩小需要记录的数据量,但仍然能达到区分引用的目的。因为这样,HotSpot中GC不是在任意位置都可以进入,而只能在safepoint处进入。 
而仍然在解释器中执行的方法则可以通过解释器里的功能自动生成出OopMap出来给GC用。

平时这些OopMap都是压缩了存在内存里的;在GC的时候才按需解压出来使用。 
HotSpot是用“解释式”的方式来使用OopMap的,每次都循环变量里面的项来扫描对应的偏移量。

对Java线程中的JNI方法,它们既不是由JVM里的解释器执行的,也不是由JVM的JIT编译器生成的,所以会缺少OopMap信息。那么GC碰到这样的栈帧该如何维持准确性呢? 
HotSpot的解决方法是:所有经过JNI调用边界(调用JNI方法传入的参数、从JNI方法传回的返回值)的引用都必须用“句柄”(handle)包装起来。JNI需要调用JavaAPI的时候也必须自己用句柄包装指针。在这种实现中,JNI方法里写的“jobject”实际上不是直接指向对象的指针,而是先指向一个句柄,通过句柄才能间接访问到对象。这样在扫描到JNI方法的时候就不需要扫描它的栈帧了——只要扫描句柄表就可以得到所有从JNI方法能访问到的GC堆里的对象。 
但这也就意味着调用JNI方法会有句柄的包装/拆包装的开销,是导致JNI方法的调用比较慢的原因之一。

OopMap介绍的更多相关文章

  1. 【转载】Java垃圾回收内存清理相关(虚拟机书第三章),GC日志的理解,CPU时间、墙钟时间的介绍

    主要看<深入理解Java虚拟机> 第三张 P84 开始是垃圾收集相关. 1. 1960年诞生于MIT的Lisp是第一门采用垃圾回收的语言. 2. 程序计数器.虚拟机栈.本地方法栈3个区域随 ...

  2. (转)JVM中的OopMap(zz)

    原文地址: http://www.cnblogs.com/strinkbug/p/6376525.html 在读周智明的深入理解JVM虚拟机时,关于枚举根节点/安全点这部分感觉书上写的不是太明白,找了 ...

  3. Java系列:JVM中的OopMap(zz)

    调用栈里的引用类型数据是GC的根集合(root set)的重要组成部分:找出栈上的引用是GC的根枚举(root enumeration)中不可或缺的一环. JVM选择用什么方式会影响到GC的实现: 如 ...

  4. JVM(四) G1 收集器工作原理介绍

    此篇文章半原创是对参考资料中的知识点进行总结,欢迎评论指点,谢谢!        部分知识点总结来自R大的帖子,下文有参考资料的链接 概述 G1 收集是相比于其他收集器(可见 上一篇文章),可以独立运 ...

  5. CSS3 background-image背景图片相关介绍

    这里将会介绍如何通过background-image设置背景图片,以及背景图片的平铺.拉伸.偏移.设置大小等操作. 1. 背景图片样式分类 CSS中设置元素背景图片及其背景图片样式的属性主要以下几个: ...

  6. MySQL高级知识- MySQL的架构介绍

    [TOC] 1.MySQL 简介 概述 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司. MySQL是一种关联数据库管理系统,将数据保存在不同的表中,而 ...

  7. Windows Server 2012 NIC Teaming介绍及注意事项

    Windows Server 2012 NIC Teaming介绍及注意事项 转载自:http://www.it165.net/os/html/201303/4799.html Windows Ser ...

  8. Linux下服务器端开发流程及相关工具介绍(C++)

    去年刚毕业来公司后,做为新人,发现很多东西都没有文档,各种工具和地址都是口口相传的,而且很多时候都是不知道有哪些工具可以使用,所以当时就想把自己接触到的这些东西记录下来,为后来者提供参考,相当于一个路 ...

  9. JavaScript var关键字、变量的状态、异常处理、命名规范等介绍

    本篇主要介绍var关键字.变量的undefined和null状态.异常处理.命名规范. 目录 1. var 关键字:介绍var关键字的使用. 2. 变量的状态:介绍变量的未定义.已定义未赋值.已定义已 ...

随机推荐

  1. spring注解开发

    applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans xm ...

  2. web-day16

    第16章WEB16-Listener&Filter篇 今日任务 使用过滤器完成自动登录的案例 使用过滤器统一网站的字符集编码 教学导航 教学目标 了解常见的监听器 理解过滤器的生命周期 能够使 ...

  3. Django URLs error: view must be a callable or a list/tuple in the case of include()

    Django 1.10 no longer allows you to specify views as a string (e.g. 'myapp.views.home') in your URL ...

  4. UIImageView的frame设置(4种方式)

    查看图片宽高后,再去设置UIImageView的frame.(不推荐) 用代码自动获取图片的宽高来设置UIImageView的frame: 创建UIImageView的同时,直接设置UIImageVi ...

  5. CI、CD和dev-ops概念

    传统的开发方式是:需求方提供文档,实现方按照文档一步步开发,中间很少变动和修改. 但是随着市场的变化,产品更新迭代的加快,也要求开放方更快的响应变化,用最短的时间开发,部署上线. 这样,持续集成(CI ...

  6. Python自动化开发 - 进程、线程(一)

    本节内容 1.操作系统发展史 2.进程和线程 3.Python threading 模块 一.操系统发展史 手工操作(无操作系统) 1946年第一台计算机诞生--20世纪50年代中期,还未出现操作系统 ...

  7. 3.Ubuntu下安装mysql并在windows下使用Navicat来连接

    一.安装mysql(只需要三条命令) 1.第一条命令(中间需要输入root用户密码): sudo apt-get install mysql-server 2.第二条命令: sudo apt-get ...

  8. 元组(tuple)基本操作

    1.定义元组,Python的元组和列表类似,不同之处在于元组中的元素不能修改(因此元组又称为只读列表),且元组使用小括号而列表使用中括号 dimensions.py , ) print(dimensi ...

  9. 分形之皇冠(Crown)

    皇冠分形曲线 核心代码: static void FractalCrown(const Vector3& vStart, const Vector3& vEnd, Vector3* p ...

  10. iOS 应用如何完全支持 IPv6-ONLY 网络?

    iOS 应用如何完全支持 IPv6-ONLY 网络?¶ 警告 您当前查看的页面是未经授权的转载! 如果当前版本排版错误,请前往查看最新版本:http://www.cnblogs.com/qin-nz/ ...