JVM分析

虚拟机

Classic VM

HotSpot

虚拟机规范

VM由编译器和执行器两个部分组成

  • 编译器:.class文件执行过程中,将.class文件编译为可执行文件,通过分层编译将热点代码编译本地可执行代码,提高执行效率
    • 标准编译
    • 分层编译,C1,C2,C3,OSR(on-stack-replace)
  • 执行器:进行程序的执行,内存的管理,VM中内存模型如下
    • 1.引用计数器,属于线程
    • 2.栈:虚拟机堆栈 (Virtual Machine stack) 调用Java方法的栈,本地方法堆栈(native method stack)调用native方法的栈
    • 3.方法区:存储class,常量,静态变量,运行时常量池(Runtime Constant Pool),存放在编译期间生成的常量(Constant Pool Table)
    • 4.堆(heap):存放 new 出来的Object
    • 5.直接内存(Direct Memory)不属于Java虚机中定义的内存空间,DirectByteBuffer引用堆外内存,避免了Java堆和Native堆来回的数据拷贝

VM中的内存按照能否被线程访问分为

  • 线程隔离:引用计数器,栈,线程独占访问的

  • 线程共享:方法区,堆,直接内存,所有的线程都可以访问

HotSpot

对象创建

1、Class的加载:classLoader,相关类型class信息加载,初始化静态变量,
2、对象分配内存:
3、对象初始化,init<构造>

对象模型

  • 头:(Header)
    1、自身运行时数据:(Mark Word)
    2、类型指针:指向class类
  • 体:(Instance)
    1、属性,FieldsAllocationStyle,要有字段对齐
  • 对齐:(Padding)

对象访问:

1.指针方式:直接指向生成的对象,垃圾收集时候需要改变每个reference的值,但是只有一次访问
2.句柄方式:在堆中划分出句柄池,存放句柄与对象的双向映射关系,垃圾收集时候,只需要改句柄,但是要经过一次访问转换

垃圾回收

内存的垃圾回收,主要做三件事情,哪些内存可以回收,怎么回收,什么时候回收

  • 1、哪些可以回收:Mark
    引用计数法(Reference Counting)
    可达性分析(Reachability Analysis):确定GC Root作为起点,向下搜索,没有被搜素到对象,称为不可达对象
    GC Root对象:
    1、虚拟机堆栈中,栈帧存在的对象
    2、方法区中,Class对象的静态变量引用的对象
    3、方法区中,Class对象常量对象
    4、本地方法栈中,栈帧存在的对象
    引用类型:新概念
    Java神存在:finalize()方法,这个方法只会调用一次

  • 2、怎么回收:Collect
    sweep 碎片,效率高
    copy 空间浪费,效率高
    compact=(sweep+copy) 效率低,无碎片

  • 3、什么时候回收:When
    安全点:到安全点,所有的线程到稳定状态
    安全区域:没明白怎么实现的

并行计算:
Sumatra Java多核并行计算引擎,

在 Java 7 以前,我们需要根据程序的特性选择对应的即时编译器。对于执行时间较短的,或者对启动性能有要求的程序,我们采用编译效率较快的 C1,对应参数 -client。

对于执行时间较长的,或者对峰值性能有要求的程序,我们采用生成代码执行效率较快的 C2,对应参数 -server。

针对新生代的垃圾回收器共有三个:Serial,Parallel Scavenge 和 Parallel New。这三个采用的都是标记 - 复制算法。其中,Serial 是一个单线程的,Parallel New 可以看成 Serial 的多线程版本。Parallel Scavenge 和 Parallel New 类似,但更加注重吞吐率。此外,Parallel Scavenge 不能与 CMS 一起使用。

针对老年代的垃圾回收器也有三个:刚刚提到的 Serial Old 和 Parallel Old,以及 CMS。Serial Old 和 Parallel Old 都是标记 - 压缩算法。同样,前者是单线程的,而后者可以看成前者的多线程版本。由于 G1 的出现,CMS 在 Java 9 中已被废弃

可移植操作系统接口(英语:Portable Operating System Interface,缩写为POSIX)
线程的 阻塞 唤醒 自旋(忙等操作)

内存分配方式:

  • 指针碰撞(Bump The Pointer)数组式的内存分配
  • 空闲列表(Free List) 列表的形式分配内存

事物性:

  • 重锁
  • 轻量锁:CAS(Compare And Set)

配置项

  • -XX:+UsePSAdaptiveSurvivorSizePolicy 根据生成对象的速率,以及 Survivor 区的使用情况动态调整 Eden 区和 Survivor 区的比例。
  • -XX:SurvivorRatio 来固定这个比例。但是需要注意的是,其中一个 Survivor 区会一直为空,因此比例越低浪费的堆空间将越高。
  • -XX:+UseTLAB (Thread Local Allocation Buffer,对应虚拟机参数 -XX:+UseTLAB,默认开启)每个线程可以向 Java 虚拟机申请一段连续的内存,比如 2048 字节,作为线程私有的 TLAB。
  • -XX:+MaxTenuringThreshold 那么该对象将被晋升(promote)至老年代
  • -XX:TargetSurvivorRatio 另外,如果单个 Survivor 区已经被占用了 50%,那么较高复制次数的对象也会被晋升至老年代。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值