三大流行jvm

sun HotSpot

ibm j9

BEA JRockit

Oracle 会基于HotSpot整合 JRockit。

jvm运行时数据区

java虚拟机所管理的内存将会包括以下几个运行时数据区域

程序计数器

1、线程私有,随线程而生,随线程而灭。

2、如果线程在执行java方法,计数器记录正在执行的虚拟机字节码指令的地址。

3、如果线程在执行native方法,计数器值为空。

java虚拟机栈

1、线程私有,随线程而生,随线程而灭。

2、java方法执行的内存模型:局部变量表、操作数栈、动态链接、方法出口等。

局部变量表:存放编译器可知的各种基本数据类型(boolean,byte,char,short,int,long,float,double)、对象引用和returnAddress类型。

本地方法栈

1、线程私有,随线程而生,随线程而灭。

2、为虚拟机使用到的native方法服务。

java堆

1、线程共享。

2、虚拟机启动时创建。

3、存放对象实例:所有的对象实例以及数组都要在堆上分配。

4、分为:年轻代(Young Generation)、年老点(Old Generation)和持久代(Permanent Generation)。

年轻代又分为:Eden空间、From Survivor空间、To Survivor空间。

java heap是GC管理的主要区域。

由于对象进行了分代处理,因此垃圾回收区域、时间也不一样。GC有两种类型:Scavenge GCFull GC

Scavenge GC

一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Scavenge GC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲出来。

Full GC

对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对整个对进行回收,所以比Scavenge GC要慢,因此应该尽可能减少Full GC的次数。在对JVM调优的过程中,很大一部分工作就是对于FullGC的调节。有如下原因可能导致Full GC:

· 年老代(Tenured)被写满

· 持久代(Perm)被写满

· System.gc()被显示调用

·上一次GC之后Heap的各域分配策略动态变化

方法区

1、线程共享。

2、存储已被虚拟机加载的类信息、常量、静态代码、jit后的代码等。

3、HotSpot中,方法区也被称为“永久代”,被GC管理。

运行时常量池:存放编译期生成的各种字面量和符号引用。可以是编辑期常量也可以是运行期生成的常量,如String的intern()方法。

直接内测

NIO引入的通道(channel)和缓存区(buffer)的I/O方式,可以使用Native函数在堆外分配内存,在java堆中通过DirectByteBuffer对象作为这块内存的引用进行操作。

JVM对象

对象创建(new)

1、检测指令的参数能否在常量池中定位到一个类的符号引用。

2、检测这个符号引用代表的类是否被加载、链接、初始化,如果没有先进行类加载。

3、为新生对象分配内存。

根据java heap是否规整,通过指针碰撞(Bump the pointer)或空闲列表(Free list)分配内存。

内存是否规整,取决于GC是否有压缩整理功能。

4、对对象进行必要设置,这些设置信息存放在对象头中。

执行完new以后执行<init>,完成对象的初始化。

对象的内存结构

对象头

1、包含两部分数据:

Mark Word:第一部分存放对象自身的运行时数据:hashcode、GC分代年龄、锁状态标志、线程持有的锁等。

类型指针:对象是哪个类的实例。

数组长度:如果是数组,记录数组长度。

实例数据

1、存放字段数据。

2、存放顺序:与虚拟机分配策略和java源码顺序相关。

HotSpot分配策略:longs/doubles、ints、shorts/chars、bytes/booleans、oops。

对齐填充

1、对象的起始地址必须是8字节的整数倍(对象大小=8字节*整数),而对象头正好是8字节的整数倍,当对象实例数据没有对齐时,需要通过对齐填充来补全。

对象访问

定位

1、通过栈上的reference数据来操作堆上的具体对象。

2、reference类型:一个指向对象的引用。在各虚拟机实现中通过使用句柄和直接指针两种方式访问堆中对象。

JDK1.2以后引用分为:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)。

四种引用强度依次逐渐解弱。

强引用

Object obj = new Object()。

只要存在强引用,就不会被GC回收。

软引用

还有用但并非必要的对象。

弱引用

强度比软引用弱。

虚引用

也称为幽灵引用

使用句柄

这个时候,Java堆上会划分一块内存作为句柄池,reference中存储的是对象的句柄地址,而句柄中又包含了对象实例数据和类型数据各自的具体地址,见下图 

句柄的好处:reference中存储的是稳定的句柄地址,对象被移动的时候,只会改变句柄中实例数据指针,reference本身不需要被修改 
直接指针

这个时候,reference存放的就是对象的地址,但是Java堆上的对象的布局就必须考虑如何存放对象类型数据的信息,见下图

指针的好处:指针的好处就是速度快,因为它的地址就是对象的地址,节省了一次指针定位的时间开销,随着对象访问的频繁,这种开销积少成多很可观

HotSpot使用直接指针。

自动内存管理

内存分配

1、对象优先分配在新生代的Eden区。

2、如果Eden区空间不足,虚拟机发起一次 新生代GC(Minor GC)。

3、大对象之间进入老生代。

4、长期存活的对象进入老年代。

5、对象年龄:对象经过一次Minor GC算一岁,默认15岁进入老年代。

对象第一次经过Minor GC,从Eden进入Survivor,在Survivor中熬过一次Minor GC年龄增加1岁。

6、动态对象年龄

如果Suivivor中相同年龄所有对象总和大于Suivivor空间的1/2,年龄大于或等于该年龄的对象直接进入老年代。

内存回收

程序计数器、虚拟机栈、本地方法栈生命周期同线程,随着线程结束内存自然回收。所以这里主要关注java heap和方法区的内存回收。

1、引用计数算法

比较古老的回收算法。原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数。垃圾回收时,只用收集计数为0的对象。此算法最致命的是无法处理循环引用的问题。

2、可达性分析(java,c#,List)

1)、通过一系列“GC Roots”的对象作为起始点,从这些点开始向下搜索。

2)、搜索的路径称为引用链(reference chain),当一个对象到GC Roots没有任何引用链,证明对象不可达,将被GC回收。

3)、GC Roots对象:

①虚拟机栈帧中的本地变量表中引用的对象。

②方法区中类静态属性引用的对象。

③方法区中常量引用的对象。

④本地方法栈中JNI引用的对象。

3、对象死亡

真正宣告死亡,需要至少两次标记。

1)、第一次标记:可达性标记后没有与GC Roots相连接的引用链。

2)、第一次筛选:是否有必要执行finalize()方法,如果要执行finalize()方法,对象被放到F-Queue队列中,由虚拟机自动执行。

3)、第二次标记:GC对F-Queue中的对象进行标记,判断是否与GC Roots可达。

4、方法区回收(持久代回收)

1)、废弃常量

以String为例,没有任何String对象引用常量池中的”abc“常量。

2)、无用的类

同时满足下面三个条件:

①该类的所有实例都已被回收。

②加载该类的ClassLoader已经被回收。

③该类对应的java.lang.class对象没有在任何地方被引用,无法再任何地方通过反射访问该类的方法。

GC算法

标记-清除算法

复制算法

标记-整理算法

分代收集算法

当前主流虚拟机采用的算法。

参考:http://pengjiaheng.iteye.com/blog/520228

垃圾收集器

HotSpot中的7中收集器。

没有最好的收集器,只有针对具体应用最合适的收集器。

参考:http://blog.csdn.net/canot/article/details/51050824

G1收集器:JDK1.7u14以后的HotSpot虚拟机

参考:http://blog.csdn.net/zhanggang807/article/details/45956325

参考

http://pengjiaheng.iteye.com/blog/524024

http://blog.csdn.net/hhb200766/article/details/46912325

jvm理论的更多相关文章

  1. jvm理论-字节码指令

    Java虚拟机的指令由一个字节长度的.代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表此操作所需参数(称为操作数,Operands)而构成. 基本数据类型 1.除了l ...

  2. jvm理论-class文件

    当JVM运行Java程序的时候,它会加载对应的class文件,并提取class文件中的信息存放在JVM的方法区内存中. Class文件组成 1.Class文件是一组以8位字节为基础单位的二进制流,各个 ...

  3. jvm理论-运行时数据区

    三大流行jvm sun HotSpot ibm j9 BEA JRockit Oracle 会基于HotSpot整合 JRockit. jvm运行时数据区 java虚拟机所管理的内存将会包括以下几个运 ...

  4. jvm理论-字节码指令案例

    案例1 public class Demo { public int calc(){ int a=100; int b=200; int c=300; return(a+b)*c; } public ...

  5. jvm理论-常量池-string

    字符串常量池-常量项(cp_info)结构 CONSTANT_String_info{ u1 tag=8; u2 string_index;//存放 CONSTANT_Utf8_info 指针 } C ...

  6. jvm实战-基本类型占多少内存

    jvm内存占用模型 对象的内存结构 对象头 Header 包含两部分数据Mark Word和Kclass: Mark Word:存储对象自身的运行时数据,如hashCode.GC分代年龄.锁状态标志. ...

  7. jvm系列

    一.jvm理论 1.1.jvm理论-总述 1.2.jvm理论-class文件 1.2.1.jvm理论-常量池-string 1.2.2.jvm理论-常量池-8种基本类型 1.3.jvm理论-字节码指令 ...

  8. JVM学习——学习方法论&学习大纲

    2020年02月06日22:25:51 完成了Springboot系列的学习和Kafka的学习,接下来进入JVM的学习阶段 深入理解JVM 学习方法论 如何去学习一门课程--方法论 多讨论,从别人身上 ...

  9. JVM的GC理论详解

    GC的概念 GC:Garbage Collection 垃圾收集.这里所谓的垃圾指的是在系统运行过程当中所产生的一些无用的对象,这些对象占据着一定的内存空间,如果长期不被释放,可能导致OOM(堆溢出) ...

随机推荐

  1. (转载)Jvm工作原理学习笔记

    一.        JVM的生命周期 1.      JVM实例相应了一个独立执行的java程序它是进程级别 a)    启动.启动一个Java程序时.一个JVM实例就产生了.不论什么一个拥有publ ...

  2. Windows通过远程桌面访问Ubuntu

    关于Windows通过远程桌面访问Ubuntu 问题及目标 Window环境通过远程桌面访问Ubuntu Ubuntu机器端   1.  安装所需软件包   sudoapt-get install x ...

  3. for_each的各种情况下的使用详解

    原创作者:http://oomusou.cnblogs.com 配合<C++ Template>(简体中文)使用 http://download.csdn.net/detail/qq239 ...

  4. 【MongoDB】在windows平台下搭建mongodb的分片集群(二)

    在上一片博客中我们讲了Mongodb数据库中分片集群的主要原理. 在本篇博客中我们主要讲描写叙述分片集群的搭建过程.配置分片集群主要有两个步骤.第一启动全部须要的mongod和mongos进程. 第二 ...

  5. 【HTML】让<pre>标签文本自动换行

    利用<pre></pre>这个标签可以将其包起来的文字排版.格式,原封不动的呈现出来. 也就是说你输入的东西被原封不动的输出,包括你输入的空格之类的,不用 和<BR> ...

  6. OCA读书笔记(1) - 浏览Oracle数据库架构

    Objectives: List the major architectural components of Oracle DatabaseExplain the memory structuresD ...

  7. hdu 4687 Boke and Tsukkomi

    Dancing link twice. Find the maximum combination numbers in the first time. Enumerate each node, dan ...

  8. mysql基础: mysql列类型--字符串

    mysql列类型:整型   http://blog.csdn.net/jk110333/article/details/9342283 mysql列类型--时间和日期  http://blog.csd ...

  9. CABasicAnimation学习Demo 包含了一些经常使用的动画效果

    个人写的一些样例: // // ViewController.m // CABasicAnimationDemo // // Created by haotian on 14-6-13. // Cop ...

  10. [置顶] Embedded Server:像写main函数一样写Web Server

    1.传统的JEE Web Server 传统的JEE中,如果我们想要部署一个Web Application,我们需要首先安装一个Container Server,如JBoss,WebLogic,Tom ...