JVM调优案例分析-Eclipse启动

为什么要进行JVM调优

运行在JVM上的程序都会进行内存分配以及垃圾回收,在这个过程中设置合理的内存大小及垃圾回收算法能显著提高应用的响应速度及运行效率,相反不合理的JVM参数设置会造成应用程序响应不稳定并导致整个应用程序挂掉。

如何JVM调优

不同类型应用程序的JVM参数设置都不一样,如何设置最优的JVM参数不仅需要对GC机制有一定的了解,而且还要反复的试验才能得出最合适的JVM参数值。
例如:某些系统要求运行稳定、并且响应速度高,这类应用就需要通过调整其JVM参数来减少内存大小调整及垃圾回收所占用的时间,以尽量的提高响应速度。报表类及容易产生大对象对响应速度要求不是很高的系统,可以把堆空间设置较大些。
除了了解GC的机制外等一些基本调优方法外,往往还需要借助一些监控工具来进行JVM参数调优,例:Jprofiler 、VisualVM、Jconsole等,通过这些工具可以监控JVM运行时内存分配情况,线程状态、数量,堆空间类、对象数量类型信息等,此外还可以借助分析垃圾回收日志对JVM进行优化。

倒排索引(反向索引)

文档矩阵

单词-文档矩阵是表达两者之间所具有的一种包含关系的概念模型。图的每列代表一个文档,每行代表一个单词,打对勾的位置代表包含关系。

从纵向即文档这个维度来看,每列代表文档包含了哪些单词,比如文档1包含了词汇1和词汇4,而不包含其它单词。从横向即单词这个维度来看,每行代表了哪些文档包含了某个单词。比如对于词汇1来说,文档1和文档4中出现过单词1,而其它文档不包含词汇1。矩阵中其它的行列也可作此种解读。
搜索引擎的索引其实就是实现“单词-文档矩阵”的具体数据结构。可以有不同的方式来实现上述概念模型,比如“倒排索引”、“签名文件”、“后缀树”等方式。但是各项实验数据表明,“倒排索引”是实现单词到文档映射关系的最佳实现方式。

贪心算法

引言

平时购物找钱时,为了使找回零钱的硬币数最少,从最大面值的币种开始,按递减的顺序考虑币种,先尽量用大面值的币种,当不足大面值币种的金额时才去考虑下一种较小面值的币种。这就贪心算法。这种方法在这里总是最优的,是因为银行对其发行的硬币种类和硬币面值的巧妙安排。
如果面值分别为1,5,11单位的硬币,而希望找回总额为15单位的硬币,按贪心算法,应该找1个11单位的硬币和4个1单位的硬币,总共找回5个硬币。但最优的解答是3个5单位面值硬币。
贪心算法并不是一个具体的算法,而是一种算法的思想,或者说是解决问题一种思路。
永远没有最好的算法,只有最适合的算法,我们选用贪心算法的原因就是因为它能够满足当前的需要并且比其他算法更加简单。

概念

贪心算法并不是整体最优考虑,它所做出的选择只是在某种意义上的局部最优(总是做出在当前看来是最好的选择)。这种局部最优选择并不能保证总能获得全局最优解,但它通常可以获得较好的近似最优解。
贪心算法在解决问题的策略上是仅根据当前已有的信息做出选择,而且一旦做出选择,不管将来有什么结果,这个选择不会改变。
贪心算法一般在开始策略选择前会进行排序,排好序后就进行最优化选择。

JVM垃圾回收算法-CMS(Concurrent Low Pause Collector)

介绍

CMS,全称Concurrent Low Pause Collector,是jdk1.4后期版本开始引入的新gc算法,在jdk5和jdk6中得到了进一步改进,它的主要适合场景是对响应时间的重要性需求 大于对吞吐量的要求,能够承受垃圾回收线程和应用线程共享处理器资源,并且应用中存在比较多的长生命周期的对象的应用。CMS是用于对Tenured Generation的回收,也就是年老代的回收,目标是尽量减少应用的暂停时间,减少Full GC发生的几率,利用和应用程序线程并发的垃圾回收线程来标记清除年老代。
在我们的应用中,因为有缓存的存在,并且对于响应时间也有比较高的要求,因此希望能尝试使用CMS来替代默认的server型JVM使用的并行收集器,以便获得更短的垃圾回收的暂停时间,提高程序的响应性。
CMS并非没有暂停,而是用两次短暂停来替代串行标记整理算法的长暂停,它的收集周期是这样。

  1. 初始标记(CMS-initial-mark)
  2. 并发标记(CMS-concurrent-mark)
  3. 重新标记(CMS-remark)
  4. 并发清除(CMS-concurrent-sweep)
  5. 并发重设状态等待下次CMS的触发(CMS-concurrent-reset)。

其中的1,3两个步骤需要暂停所有的应用程序线程的。第一次暂停从root对象开始标记存活的对象,这个阶段称为初始标记;第二次暂停是在并发标记之后, 暂停所有应用程序线程,重新标记并发标记阶段遗漏的对象(在并发标记阶段结束后对象状态的更新导致)。第一次暂停会比较短,第二次暂停通常会比较长,并且remark这个阶段可以并行标记。
而并发标记、并发清除、并发重设阶段的所谓并发,是指一个或者多个垃圾回收线程和应用程序线程并发地运行,垃圾回收线程不会暂停应用程序的执行,如果你有多于一个处理器,那么并发收集线程将与应用线程在不同的处理器上运行,显然,这样的开销就是会降低应用的吞吐量。remark阶段的并行,是指暂停了所有应用程序后,启动一定数目的垃圾回收进程进行并行标记,此时的应用线程是暂停的。
CMS的Young Generation的回收采用的仍然是并行复制收集器,这个跟Paralle GC算法是一致的。

JVM内存调整(五)

JVM运行时数据区的内存大小可以通过参数来设置,通常能设置的两块区域为堆空间和持久代(方法区),设置方法是以参数的形式来指定,Sun的HotSpot需要在JVM启动前设置这些参数,启动JVM后不能动态改变其大小。
JVM参数说明:

JVM垃圾回收(四)

垃圾回收概念

什么是垃圾回收

JVM中自动检测并移除不再使用的数据对象的这种机制称为:垃圾回收(Garbage Collection),简称GC。

GC的基本原理

JVM通过使用垃圾收集器及使用相应的垃圾回收算法将内存中不再被使用的对象进行回收。

为什么要垃圾回收

由于不同Java对象存活时间是不一定的,因此,在程序运行一段时间以后,如果不进行垃圾回收,整个程序会因内存耗尽导致整个程序崩溃。垃圾回收还会整理那些零散的内存碎片,碎片过多最直接的问题就是会导致无法分配大块的内存空间以及降低程序的运行效率。

哪些区域会被GC

VM栈、本地方法栈以及程序计数器会随方法或线程的结束而自然被回收,所以这些区域不需要考虑回收问题。堆空间和持久代(方法区)是GC回收的重点区域,不同区域对象的收集叫法不一样。

  • 对年轻代的对象的收集称为minor GC(eden:minor gc,整个新生代:major gc)。
  • 对老年代的对象的收集称为Full GC。程序中主动调用System.gc()强制执行的GC为Full GC。Full GC基本都是整个堆空间及持久代发生了垃圾回收,通常优化的目标之一是尽量减少GC和Full GC的频率。
  • 持久代的垃圾回收和老年代的垃圾回收是绑定的,一旦其中一个区域被占满,这两个区都要进行垃圾回收(Full GC)。

JVM运行数据区(三)

Runtime Data Area主要包括五个部分:

  • Heap(堆)
  • Method Area(方法区域)
  • VM Stack(虚拟机栈)
  • Native Method Stack(本地方法栈)( 在Sun的HotSpot虚拟机中VM Stack和Native method stack是合并到一起的)
  • Program Counter(程序计数器)

Heap和Method Area是被所有线程的共享使用的,而Vm Stack, Program Counter和Native Method Stack是以线程为粒度的,每个线程独自拥有。

JVM类加载器(二)

类加载器负责加载Java类的字节代码到Java虚拟机中,可以根据指定的类名(如java.lang.Object)来装载class文件的内容到Runtime Data Area中的Method Area(方法区域)。Java程序员可以extends java.lang.ClassLoader类来写自己的Class loader

类加载器的模型

类加载器双亲委派模型

如果一个类加载器接收到了类加载的请求,它首先把这个请求委托给他的父类加载器去完成,每个层次的类加载器都是如此,因此所有的加载请求都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它在搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。

双亲委派模型的优点

Java类随着它的类加载器一起具备了一种带有优先级的层次关系。例如类java.lang.Object,它存放在tools.jar中,无论哪个类加载器要加载这个类,最终都会委派给启动类加载器进行加载,因此Object类在程序的各种类加载器环境中都是同一个类。相反,如果用户自己写了一个名为java.lang.Object的类,并放在程序的Classpath中,那系统中将会出现多个不同的Object类,Java类型体系中最基础的行为也无法保证,应用程序也会变得一片混乱。

JVM体系结构(一)

本系列基于JDK7

JVM体系结构

主要包含两个子系统和两个组件。

  • Class Loader(类加载器)子系统, Execution Engine(执行引擎)子系统。
  • Runtim Data Area(运行时数据区域)组件,Native Interface(本地接口)组件。

    JVM体系结构图

Java CAS(Compare And Swap)

基础知识

CAS(Compare And Swap)比较和替换是设计并发算法时用到的一种技术。简单来说,比较和替换是使用一个期望值和一个变量的当前值进行比较,如果当前变量的值与期望的值相等,就使用一个新值替换当前变量的值。
在程序和算法中一个经常出现的模式就是Check And Act模式。先检查后操作模式发生在代码中首先检查一个变量的值,然后再基于这个值做一些操作。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×