深入理解java虚拟机<一>

来源:互联网 发布:羞羞的铁拳网络平台 编辑:程序博客网 时间:2024/06/06 03:29

一:  java虚拟机运行时数据区解析:    

                                                        

                                                      

1. 程序计数器:  线程私有,  通过改变计数器的值来选择下一步操作的字节码指令(若是native方法,则为空),包括分支,跳转,异常处理, 线程操作.

2. java虚拟机栈:线程私有, 执行java方法,存储局部变量表(八种数据类型: boolean, byte, char, int ,short, long, double, float),  操作数栈,动态链接, 方法出口等

3. 本地方法栈:线程私有, 执行native方法,作用和java虚拟机栈相同.

4. 堆: 线程共享,存放对象实例,也是GC的主要区域.

5. 方法区:线程共享, 存储类信息, 常量, 静态变量,编译后的代码.较少出现GC,一般GC在方法区只针对常量池的回收和类型的卸载.

    

二: 对象的创建和访问方式

2.1  对象的创建: 

1. 指针碰撞(Bump the point):  堆中内存为绝对规整,  已用和未用的内存整齐分开,中间放一个指针作为临界点分割器,每次创建对象,就将指针向未用的那一边挪动所分配的内存.

 所对应的GC收集算法为:  标记-整理(sign - compact),  对应的GC收集器为: Serial、ParNew(Serial的多线程版).

2.空闲列表(Free List):堆中内存散乱,需要维护一个记录内存块是否可用的列表,每次创建对象,从列表上取出对应大小的内存,并更新列表.

  所对应的GC收集算法为:  标记-清楚(Mark - Sweep),  对应的GC收集器为: CMS.

  并发情况下,使用本地线程分配缓冲(Thread Local Allocation Buffer, TLAB)即为线程预留一块内存,  参数为: -XX:+/-UseTLAB

2.2 对象的访问定位方式: 

1. 句柄访问: 堆中创建句柄池存储对象的句柄地址,好处: 对象移动时,只修改句柄地址.

2. 直接指针访问: 好处: 速度快, 节省了句柄定位的开销.(常用)

三: 垃圾收集器与算法

3.1 判断对象是否存活: 

1. 引用计数法(Reference Counting):无法解决对象相互循环引用的问题, A-B, B-A ,其他地方无用,但仍判断为可用不GC.

2. 可达性分析算法( Reachability Analysis):  通过GC Roots的引用链(Reference Chain)搜索不到,即为不可达.(常用)

  不可达的复活币: finalize()方法,若对象不可达,但执行了finalize()方法,就可以复活.

3.2 引用分类

1. 强引用(Strong Referece):  Object obj = new Object(),永不回收.

2. 软引用(Soft Reference):  有用非必需,列入二次回收范围.

3. 弱引用(Weak Reference):非必需,  活到下一次GC.

4. 虚引用(Phantom Reference):最弱,  必回收.

3.3 垃圾收集算法

1. 标记-清除算法(Mark - Sweep)

   过程:标记和回收,使用可达性分析或引用计数法进行标记,随后回收所有被标记的对象

   缺点:  1.效率: 两步效率都不高   2. 空间碎片: 产生大量不连续碎片, 大对象找不到可用内存就会触发另一次GC.

2. 复制算法(Copying)

   过程:将可用内存分为两块,每次只是用其中一块,用完以后就将对象规整的复制到另一块上,然后对这块进行GC.

   优点:不用考虑内存碎片,运行快,简单.

   缺点:因为分块了,所以每次只能使用一半内存,代价高昂.  

   运用场景:在分代收集算法中,  复制算法用来回收新生代

3. 标记-整理算法(Mrak - Compact)

   过程:和标记-清除算法一样,但后续操作不是直接对可回收对象清理,而是让所有存活对象向一端移动,然后直接清理其他.

   优点:优化了复制算法的效率

   使用场景:在分代收集算法中,标记-整理算法来回收老年代.

4. 分代收集算法(Generational Collection)(常用)

   过程: 将堆划分为新生代和老年代, 新生代划分为一个Eden区和两个Survivor区, 比例饿为8:1:1, 新生代用复制算法, 老年代用标记整理算法,

   Eden区满会触发minGC回收Eden区和一个Survivor区, 另一个Survivor用复制算法保存minGC后依然存活的对象, 并始终保持一块Survivor区是空的,.

    优点: 根据分代的思想, 针对不同对象使用不同的收集算法实现了高效, 也是现在主流的做法.

3.4 垃圾收集器

 1. Serial 收集器 

   特点: 新生代, 复制算法, 单线程

   过程: 新生代, 复制算法, 最基本的收集器, 单线程收集器, 在进行垃圾收集时,其他工作线程必须全部停掉(stop the world)

   优点: 简单高效,没有线程交互的开销,  Client模式下虚拟机很好的选择.

 2. ParNew 收集器

   特点: 新生代, 复制算法, 多线程并行

   过程: 是Serial收集器的多线程版,

   优点: 多线程下, 效率高于Serial. 且除了Serial ,只有ParNew能与CMS配合工作

 3. Parallel Scavenge 收集器

    特点: 新生代, 复制算法, 多线程并行, 吞吐量(Throughput)优先(运行代码时间/(运行代码时间+垃圾收集时间))

    过程:  同Serial

    优点: 能实现最大吞吐量,多线程 高效

 4. Serial Old 收集器

    特点: Serial 收集器的老年代版, 单线程, 标志-整理算法

    过程: 同Serial

    优点: 和Paraller Scavenge配合使用

 5. Paraller Old 收集器

   特点: Paraller Scavenge的老年代版本, 多线程, 标记-整理,算法, 

   优点: 在注重吞吐量和CPU资源敏感的场合, 可以使用Paraer Scanenge 和 Paraller Old组合

 6. CMS(Coucurrent Mark Sweep)收集器

    特点: 并发(用户线程和垃圾回收线程同步执行),  标记-清除 算法, 老年代, 并发低停顿收集器

    过程: 初始标记(STW)---并发标记---重新标记---并发清理

    优点: 并发、低停顿

    缺点: 对CPU资源敏感, 无法处理浮动垃圾(因为是并发执行), 标记清除算法带来的碎片化空间

  7. G1(Garbage-First) 收集器

    特点: 最先进, 并发与并行, 分代收集, 空间整合(标记-整理算法), 可预测的停顿

    过程: 类似CMS收集器, 将堆划分为多个大小相等的Region, 没有其他收集器在物理上隔离的新生代和老年代, 而是一堆Region的集合.

    优点: 并发并行,低停顿, 可预测的停顿

    缺点: 还不够成熟, 在吞吐量上没有超越CMS

  4. 优化java虚拟机

 1. 合理分配新生代中的区域大小 ,和老年代大小 

 2. 大对象直接进入老年代 (-XX:pretenureSizeThreshold参数,大于该值就进入老年代.)  

 3. 长期存活对象直接进入老年代(-XX:MaxTenuringThreshold参数)

 4. 使用合适的垃圾收集器

 5. GC参数

堆设置
-Xms :初始堆大小
-Xmx :最大堆大小
-XX:NewSize=n :设置年轻代大小
-XX:NewRatio=n: 设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
-XX:SurvivorRatio=n :年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
-XX:MaxPermSize=n :设置持久代大小
收集器设置
-XX:+UseSerialGC :设置串行收集器
-XX:+UseParallelGC :设置并行收集器
-XX:+UseParalledlOldGC :设置并行年老代收集器
-XX:+UseConcMarkSweepGC :设置并发收集器
垃圾回收统计信息
-XX:+PrintHeapAtGC GC的heap详情
-XX:+PrintGCDetails GC详情
-XX:+PrintGCTimeStamps 打印GC时间信息
-XX:+PrintTenuringDistribution 打印年龄信息等
-XX:+HandlePromotionFailure 老年代分配担保(true or false)
并行收集器设置
-XX:ParallelGCThreads=n :设置并行收集器收集时使用的CPU数。并行收集线程数。
-XX:MaxGCPauseMillis=n :设置并行收集最大暂停时间
-XX:GCTimeRatio=n :设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)
并发收集器设置
-XX:+CMSIncrementalMode :设置为增量模式。适用于单CPU情况。
-XX:ParallelGCThreads=n :设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。

原创粉丝点击