`
RednaxelaFX
  • 浏览: 3015165 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

最近做的两次Java/JVM分享的概要

    博客分类:
  • Java
阅读更多
这个月第一个周五和今天分别做了次Java/JVM的分享。没做新的演示稿了,之前那个巨型演示稿已经堆积得太臃肿,不适合用来做演示用。这两次都是只用很简单的本文脉络串起话题,然后把具体的讲解写在白板上。头一次效果还行,今天这次讲的内容还是枯燥了点,下面的同志们闷得睡着了一片。要讲好的话,我还需要继续花精力探索怎样的话题、怎样的深度才适合大范围的受众。

关键是:有些知识,知道了又如何?既然不能直接应用在“调优”之类的很现实的方面,那知道了没意义。但调优工作越是深入就越需要坚实的基础。呜……

话说,总觉得跟一个有C++背景的人提到vtable啥的时候都很轻松,跟只有Java背景的人讲解就麻烦不少,其实概念不难吧?Hmm

分享概要1: 2010-09-03
引用
1. 语言处理器
  语言实现: 编译器 -> 静态链接器 -> 装载器 -> 动态链接器 -> 执行
  对应到Java的一般实现形式是怎样的?
    编译器:            Java源码编译器(javac、ecj等)
    静态链接器:        不存在
    装载器+动态链接器: 类加载器
    执行:              Java虚拟机的执行引擎

2. Java源码编译器
  最重要的数据结构:抽像语法树
  抽像语法树与语法的关系
  抽像语法树与“栈”的关系

3. Class文件
  元数据
  字节码 <- 基于栈的体系结构(0地址形式的指令集)

4. Java虚拟机的基本结构
  主要组成部分: 类加载器, 自动内存管理器, 执行引擎, 运行时支持(包括线程管理等), 本地接口
  Java虚拟机的类型系统
    Java虚拟机中校验器使用的类型系统

5. Java虚拟机的执行引擎
  执行引擎负责执行字节码
  字节码指令种类:
    局部变量读/写
    算术与类型转换
    对象与数组的创建和操作
    栈操作(操作数栈)
    条件/无条件跳转
    方法调用
    抛出异常
    同步

6. Java虚拟机中的存储空间
  存储空间的一般分类: 静态存储, 半静态存储 -- 栈, 动态存储 -- 堆
  如何分配空间:
    在连续的空间中分配
    在链式结构构成的空间中分配
  
  Java虚拟机栈: 每个Java线程有一个
  Java堆:       所有Java线程共享一个
  方法区:       所有Java线程共享一个,存储“静态”数据与元数据
    运行时常量池: 每个类/接口对应一个,记录元数据/符号表
  本地方法栈

7. Java虚拟机中数据的表示
  原始类型的值
  引用类型的变量: 引用
  引用类型的值:   对象/数组的数据
  “变量a占用了多少空间?变量a指向的对象占用了多少空间?”

8. Demos, Q & A


分享概要2: 2010-09-17
引用
1. 内存管理
  1.1 内存布局(memory layout)
    操作系统提供的内存布局
      虚拟内存系统(virtual memory)
      用户地址空间布局(user address space layout) / 内核地址空间布局(kernel address space layout)
      两步式分配: reserve - commit
      Demo: windbg / vadump
    进程的地址空间组成
      保护区域
      代码(code)
      调用栈(thread stack / C stack / control stack)
      全局变量
      堆(heap / C heap)
    HotSpot中Java栈与本地方法栈的关系
      HotSpot使用操作系统的本地线程来实现Java线程
      其中每个Java线程的Java栈与本地方法栈也共用同一个操作系统提供的线程栈实现
    HotSpot的堆与GC堆的关系
      HotSpot有内部数据结构也在堆(C heap)上分配
      从Java一侧看到的GC堆是这些内部数据结构的一部分;也就是,GC堆是HotSpot的堆(C heap)的一部分
      NIO的direct buffer从HotSpot角度看是在堆上的(C heap),但从Java角度看不在堆上(GC heap)
        所以也叫“不在堆上的”(off heap)空间,这里的堆是指Java一侧看到的GC堆
    HotSpot的GC堆的布局
      除G1外,HotSpot的GC堆的布局都是 (Eden + Survivor Space × 2) + Tenured + Permanent
      Demo: Visual GC
  1.2 空间分配
    连续内存空间中的空间分配: bump-the-pointer
      e.g. C stack
    非连续空间中的空间分配: freelist
  1.3 对象布局
    HotSpot中的Java对象布局
      双字对象头(2-word object header)
      8字节对齐
      FieldsAllocationStyle
        0: Fields order: oops, longs/doubles, floats/ints, shorts/chars, bytes
        1: Fields order: longs/doubles, floats/ints, shorts/chars, bytes, oops
      CompactFields
      
      Demo: Unsafe.objectFieldOffset()

2. 方法调用
  2.1 一些术语
    方法(method)
    消息(message)
    选择器(selector) / 方法名+签名(signature)
    消息传递(message send) / 方法调用(method invocation)
    接收者(receiver)
    调用点(callsite)
  2.2 静态选择与动态分派
    静态选择(static method resolution)
      非虚方法可以静态确定单一实现版本
      虚方法可以静态确定重载版本,但无法确定实现版本
        Java语言规范第3版 8.4.9
          When a method is invoked (§15.12), the number of actual arguments
          (and any explicit type arguments) and the compile-time types of the
          arguments are used, at compile time, to determine the signature
          of the method that will be invoked (§15.12.2). If the method that
          is to be invoked is an instance method, the actual method to be
          invoked will be determined at run time, using dynamic method lookup
          (§15.12.4).
    动态分派(dynamic method dispatch)
  2.3 单分派与多分派
    单分派(single dispatch)
    多分派(multiple dispatch)
  2.4 Java中虚方法分派的本质
    签名 -> 接收者类型 -> (类型 × 签名 -> 方法) -> 方法
  2.5 虚方法的动态分派的几种实现方式
    最原始的查表
    虚方法表(virtual method table, vtable)
    内联缓存(inline cache)
      单态内联缓存(monomorphic inline cache)
      多态内联缓存(polymorphic inline cache)
      超多态的情况(megamorphic)
  2.6 JVM的5个方法调用指令
    invokestatic
    invokespecial
    invokevirtual
    invokeinterface
    invokedynamic (*)
  2.7 方法内联(method inlining)
    关键是在某个调用点“唯一确定的实现版本”
      非虚方法必然只有一个实现版本
    类层次分析(class hierarchy analysis)
      虚方法也可以被证明只有一个实现版本
    优点:可以削除方法调用的开销,更重要的是为编译器的其它优化提供机会
    缺点:有潜在的代码膨胀(code bloat)的危险

3. Demos, Q & A
分享到:
评论
11 楼 txm119161336 2018-04-10  
allocatestlye1 顺序为
  // Fields order: longs/doubles, ints, shorts/chars, bytes, oops

但是实际测试下来,
int 会排序在long 之前,这是怎么回事?
10 楼 RednaxelaFX 2010-09-29  
gstarwd 写道
期待sajiaGG下次的分享~~下次会侧重哪些方面呢? 

有个组预订了10月13号下午的一次,这次我不准备讲JVM了,讲讲茴字的四种写法…… 
大概会用计算器,或者说表达式语言(EL)为例来简单介绍语言实现的一些方式吧。大概。
9 楼 gstarwd 2010-09-29  
期待sajiaGG下次的分享~~下次会侧重哪些方面呢? 
8 楼 sohuexe 2010-09-25  
有毅力的话可以出书啊!既是压力也是动力,希望这样的书能在jdk7之前出来!
7 楼 RednaxelaFX 2010-09-22  
phz50 写道
我觉得你可以出个专栏,系统讲解jvm,零零碎碎的文章感觉看的云里雾里的,当然我是cai niao,呵呵,不过还是出个专栏把,由浅入深,照顾一下我们这些新手吧。

其实是一直很想的。开高级语言虚拟机圈子也是想更系统的整理这类资料。但很可惜现实是没足够精力来整理…开专栏只怕会烂尾 T_T
6 楼 phz50 2010-09-22  
我觉得你可以出个专栏,系统讲解jvm,零零碎碎的文章感觉看的云里雾里的,当然我是cai niao,呵呵,不过还是出个专栏把,由浅入深,照顾一下我们这些新手吧。
5 楼 RednaxelaFX 2010-09-22  
QM42977 写道
String s = "";这种方式声明的String对象是不是都在perm gen上分配?

如果你说的是Java语言,在Sun的HotSpot上跑的话,嗯是的。不只是字符串字面量,类型名、方法名、方法描述符、字段名等也都以字符串形式放在perm gen上。
4 楼 QM42977 2010-09-20  
RednaxelaFX 写道
QM42977 写道
你写的文章很棒,已经定阅了,我要好好学习!
请教一个问题:方法表是怎样分配的?


在HotSpot里的话,某个对象的vtable是分配在该对象的类(klass)对象里的,如上图。HotSpot里的klass中vtable里存的是方法对象(methodOopDesc),方法对象里有“方法入口”属性来完成虚方法分派的最后一步。vtable是在类加载的时候计算出来的。之前写了一帖涉及到了HotSpot中的对象布局,不过vtable和itable的部分没讲。有兴趣的话可以参考官网文档,VirtualCalls

String s = "";这种方式声明的String对象是不是都在perm gen上分配?
3 楼 RednaxelaFX 2010-09-19  
QM42977 写道
你写的文章很棒,已经定阅了,我要好好学习!
请教一个问题:方法表是怎样分配的?


在HotSpot里的话,某个对象的vtable是分配在该对象的类(klass)对象里的,如上图。HotSpot里的klass中vtable里存的是方法对象(methodOopDesc),方法对象里有“方法入口”属性来完成虚方法分派的最后一步。vtable是在类加载的时候计算出来的。之前写了一帖涉及到了HotSpot中的对象布局,不过vtable和itable的部分没讲。有兴趣的话可以参考官网文档,VirtualCalls
2 楼 QM42977 2010-09-18  
你写的文章很棒,已经定阅了,我要好好学习!
请教一个问题:方法表是怎样分配的?
1 楼 lwwin 2010-09-18  
诶, 啥时候我也跑来听你将讲课来~

基础差,就怕听不懂^-^~ 但是觉得会很好玩~

相关推荐

Global site tag (gtag.js) - Google Analytics