- 浏览: 92764 次
-
文章分类
最新评论
1. 垃圾回收器的工作目标是回收已经无用的对象的内存空间,从而避免内存渗漏体的产生,节省内存资源,避免程序代码的崩溃; 2. 垃圾回收器判断一个对象的内存空间是否无用的标准是:如果该对象不能再被程序中任何一个“活动的部分”所引用,此时我们就说,该对象的内存空间已经无用。所谓“活动的部分”,是指程序中某部分参与程序的调用,正在执行过程中,尚未执行完毕; 3. 垃圾回收器线程虽然是作为低优先级的线程运行,但在系统可用内存量过低的时候,它可能会突发地执行来挽救内存资源。当然其执行与否也是不可预知的; 4. 垃圾回收器不可以被强制执行,但程序员可以通过调用System.gc()方法来建议(注意,只是“建议”)执行垃圾回收器; 5. 垃圾回收器不能保证一个无用的对象一定会被及时收集,也不能保证垃圾回收器在一段Java语言代码中一定会执行。因此在程序执行过程中被分配出去的内存空间可能会一直保留到该程序执行完毕,除非该空间被重新分配或被其他方法回收。由此可见,完全彻底地根绝内存渗漏体的产生也是不可能的; 6. 我们没有办法预知在一组均符合垃圾回收器收集标准的对象中,哪一个会被首先收集。也就是说,垃圾回收的次序是不确定的; 7. 循环引用对象不会影响其被垃圾回收器收集; 8. 为了更快的让垃圾回收器收集不再有用的对象,可以通过将对象的引用变量(reference variables)设置为null值,来暗示垃圾回收器来收集该对象。
这里重点说明的是,虽然就像你无法直接命令保洁人员倒垃圾一样,你无法直接操作Java进行垃圾回收操作,但并不意味着你对此无能为力。比如上面的第四条,System.gc()方法,但是可以很负责任的说,它,基本,没有用。特别是相对于第八条来说,人家还来得跟实惠些。就是将对象的引用变量(reference variables)设置为null值。至于什么是对象,什么是引用变量什么是null,那些都是浮云,以后你自会清楚地。不过难免有的笔试题里面,特别是有的公司会出一些Java的古老的面试题,你还得直到这个方法。
1960年 MIT(麻省理工学院 Massachusetts Institute of Technology )Lisp语言 第一次使用动态内存分配和垃圾收集技术;
那些内存需要被释放
在什么时候释放
怎样实现释放
程序计数器、jvm栈、本地方法栈随 线程创建和释放(不由GC回收),jvm栈中的栈帧随方法的进入和退出顺序执行入栈和出栈,每个栈帧的大小在编译时确定(无动态扩张情况);
垃圾收集器对堆回收前,判断对象在后面的程序还要被调用,或者不再被调用;
判断方法
1、引用计算法:在调用时,计数器值+1;调用结束时,计数器值-1;当计数器值为0时不能再被调用,适用大部分gc算法;但不能解决对象循环互调;
2、可达性分析算法 通过"GC Roots"对象作为起始点,从起始节点开始向下搜索,走过的路径称为引用链(reference chain),当一个对象与GC Roots没有链接时,则该对象是不可用的。
可以作为GC Roots对象包括:
jvm栈(栈中本地变量表)中引用的对象
方法区中类静态属性引用的对象
方法区中常量引用的对象 (单例模式 final A a;)
JNI(c++)中引用的对象
1.2之后对引用进行看扩充,将引用分为:
强引用(String Reference),类似 A a = new A(),只要a还会使用,收集器不会收集a空间
软引用(Soft Reference), 弱引用被回收后,还是不能消除内存溢出,溢出前回收 软引用空间
弱引用(Weak Reference),下次gc收集垃圾时,被回收
虚引用(Phantom Reference);关联对象,在对象被回收之前返回一个系统信息,不能通过虚引用取得实例,该空间已被回收;
对象的自我救赎finalize()
一个对象被回收前至少要经历两次标记,可达性分析后发现与GC Roots没有连接时,将进行第一次标记, 并筛选该对象是否需要执行finalize()方法; 如果该对象被判定有必要执行finalize方法则将放入F-Queue列队,由低级Finalizer线程去触发它,finalize()提供给对象最后一次不回收的机会,只要和引用链上任何一个对象建立关联即可:
public class Test { public static Test t=null; public void isAlive(){ System.out.println("still here"); } protected void finalize(){ System.out.println("执行finalize方法"); t = this; //自我引用 } public static void main(String...s) throws Exception{ t = new Test(); t=null; System.out.println("is here ?"); System.gc(); //执行gc()时触发finalize()方法,finalize方法优先级很低,不设置等待,就会出现没有执行就执行下一条语句了; Thread.sleep(500); t.isAlive(); System.out.println(t.hashCode()); //执行了finalize()方法,t复活了,但只能复活一次,若再执行: t=null; System.out.println("is here ?"); System.gc(); Thread.sleep(500); //判定对象t是否还在heap中存在 System.out.println(t==null); } }
输出:
is here ?
执行finalize方法
still here //heap中还存在
5629279
is here ?
true //表示已被回收
回收方法区,jvm规范中讲过可以不要求jvm对方法区的垃圾回收,因为能释放的空间很少。永久代的垃圾收集主要有两部分:废弃常量和无用的类。
回收常量与回收heap类似,而回收无用的类比较复杂,判断是否为无用的类:
java heap中不存在该类的任何实例
该类的类类加载已经被回收
该类的Class对象没有被任何地方引用
垃圾收集算法:
标记-清除(Mark- sweep)
标记-整理(Mark- compact)
复制(Copying)(两块内存)
分代收集算法(老年代、新生代)
新生代中98%的会被回收,将新生代分为Eden(大块)、两个survival;每次使用Eden和其中一个survival,当回收时,将Eden和survival中存活的对象一次性的复制到另外一块survival空间上,然后格式化Eden和刚才用过的survival空间,HotSpot默认Eden与survival大小比例8:1,新生代中的90%用来装载新生对象,10%用来转载存活的对象。
垃圾收集器是垃圾收集算法的具体实现。Java规范对垃圾收集器的实现没有做任何规定,因此不同的虚拟机提供的垃圾收集器可能有很大差异。HotSpot虚拟机1.7版本使用了多种收集器。(HotSpot使用G1的垃圾收集器)
![](http://dl2.iteye.com/upload/attachment/0106/2389/79ccb914-6eda-3838-a73f-b05c0ac56afc.jpg)
共有7种作用不不同分代的收集器,其中Serial、ParNew、Parallel Scavenge(并行清除)属于新生代收集器,CMS、Serial Old(MSC) Parallel Old属于老年代收集器,G1可以作用于这两部分。相互连线表示收集器可以搭配使用。
1、Serial (连续的、串行)收集器
Serial收集器是最基本、发展历史最为悠久的收集器。在曾经的JDK1.3之前是新生代收集的唯一选择。
这个收集器是一个单线程的收集器(即只会使用一个CPU或一条收集线程),在它进行垃圾收集的时,必须暂停其他所有的工作线程(Stop The World),直到它收集结束。这个过程是由虚拟机后台发起并自动完成的,对用户不可见的情况下把用户正常的工作线程全部停掉,这对许多应用是无法接受的。
![](http://dl2.iteye.com/upload/attachment/0106/2392/e1a05305-684c-3f9f-834b-f9758dee1b5f.jpg)
为了消除或减少“Stop The World”停顿,从Serial 到Parallel(平行的、并行) 收集器,再到Concurrent Mark Sweep(CMS 并发标记-清除)到Garbage First(G1)收集器,越来越复杂,性能也越来越好,用户停顿时间越来越小。虽然Serial有着这一无法消除的影响,但是它仍旧是虚拟机运行在Client 模式下的默认新生代收集器。在单CPU环境来说,Serial 由于没有线程交互的开销,专心做垃圾收集,因而具有最高的收集效率。在用户的桌面应用中,分配给虚拟机的内存一般不会很大,收集一两百M的新生代所用的停顿时间完全可以控制在一百ms之内。所以,Serial收集器对于运行在Client模式下的虚拟机来说是一个很好地选择。收集器可用的控制参数如下:
-XX:+UserSerialGC 在新生代和老年代使用串行收集器
-XX:+SurvivorRatio 设置eden和survivor区大小的比例
-XX:+PretenureSizeThreshold 直接晋升到年老代的对象大小,设置此参数后,超过该大小的对象直接在年老代中分配内存
-XX:+MaxTenuringThreshold 直接晋升到年老代的对象年龄,每个对象在一次Minor GC之后还存活,则年龄加1,当年龄超过该值时进入年老代
2、ParNew收集器
ParNew 收集器其实就是serial 收集器的多线程版本,除了使用多条线程进行垃圾收集之外,其余行为与Serial收集器一样。但它却是Server模式下的虚拟机中首选的新生代收集器,与性能无关的一个原因是,除了Serial收集器外,只有它能与CMS收集器配合工作,后者是HotSpot 虚拟机中第一款真正意义上的并发(Concurrent)收集器,它第一次实现了让垃圾收集线程与用户线程同时工作。
在多核多线程系统中,使用-XX:ParallelGCThreads参数限制垃圾收集线程数。
ParNew收集器也是使用-XX:+UseConcMarkSweepGC选项后的默认新生代收集器,也可以使用-XX:+UseParNewGC来指定它。
关于垃圾收集中的并发和并行,可以解释如下.
并行(Parallel):指多条垃圾收集线程并行工作,用户线程仍处于等待状态。
并发(Concurrent):指用户线程与垃圾收集线程同时执行,用户程序继续运行,而垃圾收集程序运行在另一个cpu上。
3、Parallel Scavenge (并发清除)收集器
Parallel Scavenge收集器也是新生代收集器,使用复制算法,也是并行的多线程收集器,和ParNew 大致一样。但是Parallel Scavenge 的关注点与其他收集器不同,CMS等关注于尽可能缩短用户线程停顿时间,而Parallel Scavenge目标则是达到一个可控制的吞吐量(Throughput)。所谓吞吐量就是CPU用于运行用户代码的时间与CPU总消耗的时间的比值,如虚拟机运行了100分钟,垃圾收集花掉了1分钟,那么吞吐量便是99%。
-XX:+UseParNewGC 打开此开关参数后,使用ParNew+Serial Old收集器组合进行垃圾收集。
-XX:+UseParallelOldGC 打开此开关参数后,使用Parallel Scavenge+Parallel Old收集器组合进行垃圾收集。
-XX:+ParallelGCThreads 设置并行GC时进行内存回收的线程数。
-XX:+MaxGCPauseMillis Parallel Scavenge收集器最大GC停顿时间(>0)。
-XX:GCTimeRatio 直接设置吞吐量大小(0-100)。
-XX:+GCTimeRation Parallel Scavenge收集器运行时间占总时间比率。
-XX:+UseAdaptiveSizePolicy java虚拟机动态自适应策略,动态调整年老代对象年龄和各个区域大小。
4、Serial Old 收集器jdk1.5
Serial Old 收集器是Serial 的老年代版本,同样是一个单线程收集器,使用“标记-整理”算法。主要意义也是在Client 模式下使用。
5、Parallel Old 收集器jdk1.6
Parallel Old是Parallel Scavenge 收集器的老年代版本,使用多线程和“标记-整理”算法。
在它出现之前,由于新生带收集器Paralle Scavenge 只能和Serial Old 配合,老年代Serial Old 收集器是单线程而Paralle Scavenge是多线程,即使使用Parallel Scavenge 收集器也不能在整体应用上获得吞吐量最大化的效果。这种组合甚至不如 ParNew (多线程)+ CMS 的组合给力。直到 Parallel Old的出现。 Parallel Old工作过程如下图。
![](http://dl2.iteye.com/upload/attachment/0106/2394/b27c988b-56e1-33d7-b19d-ed6f0c7c11fe.jpg)
6、CMS 收集器
CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。主要用于互联网或B/S系统的服务端,这类应用尤其重视服务的响应速度。
前面的都是并行收集器,CMS是整体上市并发的(低停顿收集器);
从名字可以看出,CMS是基于“标记-清除”算法的,运作过程更加复杂一些,分为4个步骤:
①.初始标记(CMS initial mark) 标记GC Roots直接关联的对象
②.并发标记(CMS concurrenr mark) 可达性分析算法
③.重新标记(CMS remark) 并发变动修改
④.并发清除(CMS concurrent sweep)
其中初始标记、重新标记这两个步骤任然需要停顿其他用户线程。初始标记仅仅只是标记出GC ROOTS能直接关联到的对象,速度很快,并发标记阶段是进行GC ROOTS 根搜索算法阶段,会判定对象是否存活。而重新标记阶段则是为了修正并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间会比初始标记阶段稍长,但比并发标记阶段要短。由于整个过程中耗时最长的并发标记和并发清除过程中,收集器线程都可以与用户线程一起工作,所以整体来说,CMS收集器的内存回收过程是与用户线程一起并发执行的。执行过程如下图。
![](http://dl2.iteye.com/upload/attachment/0106/2396/a9372fd6-b770-33a9-a63f-53c72ef423c3.jpg)
CMS收集器的优点:并发收集、低停顿,但是CMS还远远达不到完美,主要有三个显著缺点:
CMS收集器对CPU资源非常敏感。在并发阶段,虽然不会导致用户线程停顿,但是会占用CPU资源而导致引用程序变慢,总吞吐量下降。CMS默认启动的回收线程数是:(CPU数量+3) / 4。
CMS收集器无法处理浮动垃圾,可能出现“Concurrent Mode Failure“,失败后而导致另一次Full GC的产生。由于CMS并发清理阶段用户线程还在运行,伴随程序的运行自热会有新的垃圾不断产生,这一部分垃圾出现在标记过程之后,CMS无法在本次收集中处理它们,只好留待下一次GC时将其清理掉。这一部分垃圾称为“浮动垃圾”。也是由于在垃圾收集阶段用户线程还需要运行,即需要预留足够的内存空间给用户线程使用,因此CMS收集器不能像其他收集器那样等到老年代几乎完全被填满了再进行收集,需要预留一部分内存空间提供并发收集时的程序运作使用。在默认设置下,CMS收集器在老年代使用了68%的空间时就会被激活,也可以通过参数-XX:CMSInitiatingOccupancyFraction的值来提供触发百分比,以降低内存回收次数提高性能。要是CMS运行期间预留的内存无法满足程序其他线程需要,就会出现“Concurrent Mode Failure”失败,这时候虚拟机将启动后备预案:临时启用Serial Old收集器来重新进行老年代的垃圾收集,这样停顿时间就很长了。所以说参数-XX:CMSInitiatingOccupancyFraction设置的过高将会很容易导致“Concurrent Mode Failure”失败,性能反而降低。
CMS是基于“标记-清除”算法实现的收集器,使用“标记-清除”算法收集后,会产生大量碎片。空间碎片太多时,将会给对象分配带来很多麻烦,比如说大对象,内存空间找不到连续的空间来分配不得不提前触发一次Full GC。为了解决这个问题,CMS收集器提供了一个-XX:UseCMSCompactAtFullCollection开关参数,用于在Full GC之后增加一个碎片整理过程,还可通过-XX:CMSFullGCBeforeCompaction参数设置执行多少次不压缩的Full GC之后,跟着来一次碎片整理过程。
7、G1 收集器jdk1.7
G1 是面向服务端应用的垃圾收集器。具有如下几个特点。
并行与并发:G1能充分利用多CPU、多核环境下的硬件优势,使用多个CPU(CPU或者CPU核心)来缩短Stop-The-World停顿的时间,其他(除CMS)收集器原本需要停顿Java线程,G1收集器仍然可以通过并发的方式让Java程序继续执行。
分代收集:与其他收集器一样,分代概念在G1中依然得以保留。虽然G1可以不需其他收集器配合就能独立管理整个GC堆,但它能够采用不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次GC的旧对象以获取更好的收集效果。
空间整合:与CMS的“标记-清理”算法不同,G1从整体看来是基于“标记-整理”算法实现的收集器,从局部(两个Region之间)上看是基于“复制”算法实现,无论如何,这两种算法都意味着G1运作期间不会产生内存空间碎片,收集后能提供规整的可用内存。这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次GC。
可预测的停顿:这是G1相对于CMS的另外一大优势,降低停顿时间是G1和CMS共同的关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒,这几乎已经是实时Java(RTSJ)的垃圾收集器特征了。
在G1之前的其他收集器进行收集的范围都是新生代和老年代,而G1收集时,java堆的内存布局与其他收集器有很大区别,它将整个java堆划分为多个大小相等的独立区域(region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都属于Region集合。
G1收集器之所以能建立可预测的停顿时间模型,因为它可以避免全堆内存的垃圾收集(使用Remembered Set避免全堆扫描)。G1跟踪各个Region里面的垃圾堆积的价值大小(回收后会获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回价值最大的Region(这也就是Garbage-First名称的来由)。这种使用Region划分内存空间以及有优先级的区域回收方式,保证了G1收集器在有限的时间内获可以获取尽可能高的收集效率。
G1收集器的运作大致可划分为以下几个步骤:
初始标记(Initial Marking)
并发标记(Concurrent Marking)
最终标记(Final Marking)
筛选回收(Live Data Counting and Evacuation)
![](http://dl2.iteye.com/upload/attachment/0106/2398/696ec49c-300e-376d-8e48-51b63de9d014.jpg)
gc日志:
JVM的GC日志的主要参数包括如下几个:
-XX:+PrintGC 输出GC日志
-XX:+PrintGCDetails 输出GC的详细日志
-XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)
-XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息
-Xloggc:D:/Documents/gc.log 日志文件的输出路径
在eclipse中参数设置中添加:
Java代码 收藏代码
-XX:+PrintGCDetails
-XX:+PrintHeapAtGC
-XX:+PrintGCDateStamps
-XX:+PrintTenuringDistribution
-verbose:gc
-Xloggc:D:/Documents/gc.log
打开文件:
Java代码 收藏代码
Heap
def new generation total 4928K, used 691K [0x248f0000, 0x24e40000, 0x29e40000)
eden space 4416K, 15% used [0x248f0000, 0x2499cf80, 0x24d40000)
from space 512K, 0% used [0x24d40000, 0x24d40000, 0x24dc0000)
to space 512K, 0% used [0x24dc0000, 0x24dc0000, 0x24e40000)
tenured generation total 10944K, used 0K [0x29e40000, 0x2a8f0000, 0x348f0000)
the space 10944K, 0% used [0x29e40000, 0x29e40000, 0x29e40200, 0x2a8f0000)
compacting perm gen total 12288K, used 146K [0x348f0000, 0x354f0000, 0x388f0000)
the space 12288K, 1% used [0x348f0000, 0x34914b50, 0x34914c00, 0x354f0000)
ro space 10240K, 45% used [0x388f0000, 0x38d77290, 0x38d77400, 0x392f0000)
rw space 12288K, 54% used [0x392f0000, 0x3997ace8, 0x3997ae00, 0x39ef0000)
参看:http://blog.csdn.net/huangzhaoyang2009/article/details/11860757
http://wentao365.iteye.com/blog/1142837
对象的内存分配,一般就是在堆上分配空间,对象主要分配在新生代的Eden区上,如果启动了本地线程分配缓冲,将按线程优先在TLAB(缓存)上分配。也可能会直接分配在老年代中,分配的规则并不是百分之百固定的,其细节取决于当前使用的是哪一种垃圾收集器组合,还有虚拟机中与内存相关的参数的设置。
1、对象优先在Eden分配
大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够的空间进行分配时,虚拟机将发起一次Minor GC。
2、大对象直接进入老年代
大对象就是指需要大量连续内存空间的Java对象,典型大对象:长字符串及数组。大对象对虚拟机的内存分配来说就是一个坏消息(遇到一群“朝生夕灭”的“短命大对象”,写程序时应当避免),经常出现大对象容易导致内存还有不少空间时就提前触发垃圾收集以获取足够的连续空间来“安置”它们。
虚拟机提供了一个-XX:PretenureSizeThreshold=3*1024*1024参数,令大于这个设置值的对象直接在老年代中分配。这样做的目的是避免在Eden区及两个Survivor区之间发生大量的内存拷贝
3、长期存活的对象将进入老年代
内存回收时应该识别哪些对象应当放在新生代,哪些对象应放在老年代中。为了做到这点,虚拟机给每个对象定义了一个对象年龄(Age)计数器。如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中,并将对象年龄设为1。对象在Survivor区中每熬过一次Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认为15岁)时,就会被晋升到老年代中。对象晋升老年代的年龄阈值,可以通过参数-XX:MaxTenuringThreshold=15来设置。
4、 动态对象年龄判定
为了能更好地适应不同程序的内存状况,虚拟机并不总是要求对象的年龄必须达到MaxTenuringThreshold才能晋升老年代,如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄。
5、空间分配担保
在发生Minor GC时,虚拟机会检测之前每次晋升到老年代的平均大小是否大于老年代的剩余空间大小,如果大于,则改为直接进行一次Full GC。如果小于,则查看HandlePromotionFailure设置是否允许担保失败;如果允许,那只会进行Minor GC;如果不允许,则也要改为进行一次Full GC。大部分情况下都还是会将HandlePromotionFailure开关打开,避免Full GC过于频繁。
在java/bin目录中除了java.exe和javac.exe之外,还有很多exe文件, 这些执行文件大多数是java\lib\tools.jar类库的一层薄包装而已,它们主要的功能代码是在tools类库中实现的。
Sun JDK 监控和故障处理工具
(1)jps:JVM process Status Tool,显示指定系统内所有的HotSpot虚拟机进程
(2)jstat:JVM Statistics(统计) Monitoring(检测) Tool,用于收集HotSpot虚拟机各方面的运行数据
(3)jinfo:Configuration Info for Java,显示虚拟机配置信息
(4)jmap:Memory Map for Java,生成虚拟机的内存转储快照(heapdump文件)
(5)jhat:JVM Heap Dump(仓库) Browser,用于分析headdump文件,它会建立一个HTTP/HTML服务器,让用户可以在浏览器上查看分析结果
(6)jstack:Stack Trace(跟踪) for Java,显示虚拟机的线程快照
1、 jps:虚拟机进程状况工具
它的作用是显示当前系统的java进程情况,及其id号。我们可以通过它来查看我们到底启动了几个java进程(因为每一个java程序都会独占一个java虚拟机),和他们的进程号(为下面几个程序做准备),并可通过opt来查看这些进程的详细启动参数。
使用方法:在当前命令行下打 jps(需要JAVA_HOME,没有的话,到改程序的目录下打) 。
C:\Users\skx>jps
7508 Jps //这个是变化的
4564 org.eclipse.equinox.launcher_1.3.0.v20140415-2008.jar
C:\Users\skx>jps -q
1132
4564
C:\Users\skx>jps -m
8116 Jps -m
4564 org.eclipse.equinox.launcher_1.3.0.v20140415-2008.jar -os win32 ..... ......
C:\Users\skx>jps -l
4564 D:\ZmyExe\eclipse-jee-luna-R-win32\eclipse\\plugins/org.eclipse.equinox.launcher_1.3.0.v20140415-2008.jar
3940 sun.tools.jps.Jps
C:\Users\skx>jps -v
2100 Jps -Dapplication.home=D:\ZmyExe\java -Xms8m
4564 org.eclipse.equinox.launcher_1.3.0.v20140415-2008.jar -Dosgi.requiredJavaVersion=1.6 -Xms40m -Xmx512m -XX:MaxPermSize=256m
2、jstat:虚拟机统计信息监视工具
用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或远程(需要远程主机提供RMI支持,Sun提供了jstatd工具可以方便地建立远程RMI服务器)虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据,在没有GUI图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。
先查出jvm的线程jps 在使用jstat;
格式如:C:\Users\skx>jstat -class 4564
Loaded Bytes Unloaded Bytes Time
17788 21748.5 101 72.7 10.91
jstat命令格式为:
jstat option vmid [interval count]
使用gcutil:
C:\Users\skx>jstat -gcutil 4564
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 0.00 1.68 50.48 99.87 24 0.272 47 11.143 11.415
参数解释:
Options — 选项,上面列出的选项
vmid — VM的进程号,即当前运行的java进程号
interval– 间隔时间,单位为毫秒
count — 打印次数,如果缺省则打印无数次
S0 — Heap上的 Survivor space 0 区已使用空间的百分比
S1 — Heap上的 Survivor space 1 区已使用空间的百分比
E — Heap上的 Eden space 区已使用空间的百分比 (新生代)
O — Heap上的 Old space 区已使用空间的百分比
P — Perm space 区已使用空间的百分比 permanent
YGC — 从应用程序启动到采样时发生 Young GC 的次数
YGCT– 从应用程序启动到采样时 Young GC 所用的时间(单位秒)
FGC — 从应用程序启动到采样时发生 Full GC 的次数
FGCT– 从应用程序启动到采样时 Full GC 所用的时间(单位秒)
GCT — 从应用程序启动到采样时用于垃圾回收的总时间(单位秒)
对于命令格式中的vmid与LVMID需要特别说明一下:如果是本地虚拟机进程,VMID和LVMID是一致的,如果是远程虚拟机进程,那VMID的格式应该是:
[protoco:][//]lvmid[@hostname[:port]/servername]
参数interval和count代表查询间隔和次数,如果省略这两个参数,说明只查询一次,假设需要每秒查询一次进程号4564垃圾收集的情况,一个查询10次,那命令应该是
C:\Users\skx>jstat -gc 4564 1000 10
3、 jinfo:Java配置信息工具
jinfo命令格式:
jinfo [ option ] pid
Java代码 收藏代码
where <option> is one of:
-flag <name> to print the value of the named VM flag
-flag [+|-]<name> to enable or disable the named VM flag
-flag <name>=<value> to set the named VM flag to the given value
-flags to print VM flags
-sysprops to print Java system properties
<no option> to print both of the above
-h | -help to print this help message
4、 jmap:Java内存映像工具
jmap命令格式:
jmap [ option ] vmid
5、jhat:虚拟机堆转储快照分析工具
Sun JDK提供jhat(JVM Heap Analysis Tool)命令与jmap命令搭配使用,来分析jmap生成的堆存储快照。jhat内置了一个微型的HTTP/HTML服务器,生成dump文件的分析结果后,可以在浏览器中查看。
6、jstack:Java堆栈跟踪工具
jstack(Stack Trace for Java)命令用于生成虚拟机当前时刻的线程快照(一般称为threaddump或javacore文件)。线程快照就是当前虚拟机内每一条线程正在执行的方法的堆栈的机会,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等都是导致线程长时间停顿的常见原因。线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做些什么事情,或者等待着什么资源。
jstack命令格式:
jstack [ option ] vmid
option选项的合法值与具体含义为:
(1)-F : 当正常输出的请求不被响应时,强制输出线程堆栈
(2)-l:除堆栈外,显示关于锁的附加信息
(3)-m:如果调用到本地方法的话,可以显示C/C++的堆栈
JDK的可视化工具
1、JConsole:Java监视与管理控制台
2、VisualVM:多合一故障处理工具(需要下载安装)
发表评论
-
28、ide---helper
2015-04-13 10:03 01、Eclipse 安装反编译插件jadclipse(经验总结 ... -
Private2、Map --->Model
2015-04-04 09:22 01、mybatis --->interface Ma ... -
Private1、Javabean <---->json
2015-04-04 08:30 01、简单生成 ---- jsonTree easyUI- ... -
lll.单列
2015-03-11 13:32 0概括起来,要实现“单子设计模式”,可以利用下面的方式来完成: ... -
####.Java分隔符
2015-03-11 13:21 01.分号 在Java中语句的 ... -
JSF1.1和JSF1.2之间表达式语言的变化(转)
2015-03-09 21:11 0JavaServer Faces 1.1和1,.2版之间最基本 ... -
27、Java加密技术(九)——SSL(CA)
2015-04-02 11:39 470<转>http://snowolf.iteye.c ... -
26、Java加密技术(八)——数字证书
2015-03-31 14:40 503<转>http://snowolf.iteye.c ... -
25、Java加密技术(七)——非对称加密算法最高级ECC
2015-03-31 14:40 694<转>http://snowolf.iteye.c ... -
24、Java加密技术(六)——数字签名算法DSA
2015-03-31 14:40 602<转>http://snowolf.iteye.c ... -
23、Java加密技术(五)——非对称加密算法的由来DH
2015-03-31 14:39 560<转>http://snowolf.iteye.c ... -
22、Java加密技术(四)——非对称加密算法RSA
2015-03-31 14:39 609<转>http://snowolf.iteye.c ... -
21、Java加密技术(三)——PBE算法
2015-03-12 15:19 785<转>http://snowolf.iteye.c ... -
20、Java加密技术(二)——对称加密算法DES&AES
2015-03-09 10:39 546<转>http://snowolf.iteye.c ... -
18、byte数据类型
2015-03-09 09:33 481-2^7 - 2^7-1(-128 ~ 127) ... -
17、String <--->基本数据类型
2015-03-09 09:33 500基本类型 <--> String转换 int ... -
19、java加密技术(一)-BASE64与单向加密算法MD5&SHA&MAC
2015-03-09 10:15 469<转>http://snowolf.iteye.c ... -
16、switch用法
2015-03-06 07:57 478Java 语言怎样对字符串进行switch多项判断操作? 换j ... -
lll.Q&A
2015-03-05 13:16 01、interface 为什么不能实例化对象? -
lllll、Exception
2015-03-04 13:12 481web.xml The reference to entity ...
相关推荐
对Java开发人员而言,理解这些内存管理机制不仅能够帮助其编写出更加稳定和高效的代码,还能在发生内存问题时迅速定位和解决问题。随着JDK版本的更新,内存管理的机制和参数也在不断地优化和演进,开发者需要不断...
JVM内存管理是Java虚拟机的核心机制之一,其主要包含对象的创建、内存分配、垃圾回收以及内存释放等过程。在JVM中,垃圾回收(GC)是自动管理内存的关键技术,其目的是回收不再使用的对象所占用的内存空间,以避免...
在这份由Sun Microsystems公司出版的《JVM内存管理白皮书》中,我们可以找到关于Java虚拟机(JVM)内存管理的详细介绍和深入分析。这份文档对于想要深入了解JVM工作原理的读者来说是一份宝贵的学习资料。在这份...
1. 垃圾收集器:JVM的内存管理主要依赖垃圾收集器,不同的收集器有不同的工作策略。例如,新生代的Serial、ParNew和G1,老年代的Parallel Old、CMS和ZGC等。理解这些收集器的工作机制是调优的基础。 2. 内存配置:...
3. **内存管理**:详细讲解堆内存、栈内存、方法区、程序计数器、本地方法栈等区域的分配与回收,特别是垃圾收集机制,如分代收集、标记-清除、复制算法、标记-整理、CMS和G1等。 4. **字节码执行**:解释字节码...
JVM是一种运行Java字节码的虚拟机,它负责垃圾回收、内存管理、类加载以及性能优化等工作。JVM分析器的主要目标是对JVM的内存使用、CPU消耗、线程活动、类加载情况等进行实时监测,以便于定位性能瓶颈和内存泄漏等...
JVM通过类加载器、运行时数据区、执行引擎、本地方法接口和垃圾收集机制等组件协同工作,确保Java程序的高效运行。 2. **类加载机制** JVM的类加载机制包括加载、验证、准备、解析和初始化五个阶段。"jvm-demo...
1. **垃圾收集算法**:了解并选择合适的垃圾收集器,如Serial、Parallel、CMS、G1等,每种收集器有不同的性能特点。 2. **GC调优**:通过调整新生代与老年代的比例、设置初始堆大小、最大堆大小等参数,减少垃圾回收...
深入理解JVM内存分配、垃圾收集(Garbage Collection, GC)原理以及垃圾收集器的工作方式对于优化程序性能至关重要。 首先,我们要了解JVM内存结构。在Java中,内存主要分为以下几个区域: 1. **堆内存(Heap)**...
JVM垃圾收集器是Java虚拟机(JVM)中的一种自动内存管理机制,负责回收Java程序中不再使用的对象,以避免内存泄漏和提高程序性能。Java中有多种垃圾收集器,每种垃圾收集器都有其特点、优劣势和使用场景。 1. ...
本文将基于“JVM内存模型和垃圾收集”的主题,深入探讨JVM中的内存管理机制以及垃圾收集的相关技术细节。 #### 二、JVM内存模型概述 JVM内存模型主要涉及以下几个关键概念: 1. **堆(Heap)** - **定义**:堆是...
Java虚拟机(JVM)是Java程序运行的基础,它的垃圾收集器(GC)是自动管理内存的核心机制。在Java应用程序中,尤其是对于大型系统或高并发环境,进行JVM GC调优是提升性能、减少系统停顿时间的关键步骤。"用于测试...
Java虚拟机(JVM)是Java程序运行的基础,它的全称是Java Virtual Machine。在Java应用程序执行过程中,JVM负责管理内存,包括对象的...深入理解JVM内存管理,特别是GC机制,对于成为一名优秀的Java开发者至关重要。
Sun JDK 1.6 的垃圾收集器(GC)是其内存管理的关键组成部分,它负责自动地回收不再使用的对象所占用的内存。本文将详细介绍Sun JDK 1.6 GC的工作原理、内存管理机制以及调优技巧。 #### 二、为什么学习GC? - **...
在Java编程中,JVM(Java虚拟机)的垃圾回收机制是自动管理内存的重要部分。垃圾回收机制负责回收那些不再被程序使用、即无法达到的对象所占用的内存空间。我们通过深入探讨以下几个关键点来理解JVM垃圾回收机制的...
Java 堆也是垃圾收集器管理的主要区域,如果从内存回收的角度看,由于现在收集器采用分代收集算法所以可以分为老年代和新生代,再细致有 Eden 空间、from 空间、to 空间,但是无论怎么划分,它都是只是存储对象实例...
- **垃圾收集器的选择与配置**:不同的垃圾收集器有不同的性能特征,选择合适的垃圾收集器并进行合理配置,可以有效提升系统性能。例如,CMS(Concurrent Mark Sweep)适合低暂停时间需求,G1(Garbage-First)则...
这个“jvm-training”资料包涵盖了JVM的核心概念、内存管理、垃圾回收机制、性能优化等方面的知识。 1. **JVM架构** - 类加载器:JVM通过类加载器将.class文件加载到内存,分为引导类加载器、扩展类加载器和应用...
- 垃圾回收:研究不同垃圾收集器的工作原理,如Serial、Parallel、CMS、G1等。 - 内存区域:分析堆、栈、方法区、程序计数器和本地方法栈的功能。 - 虚拟机调优:学习JVM参数设置,如何优化内存分配和垃圾回收...
在"jvm-int-gc-benchmark"项目中,我们可以通过基准测试来评估和比较不同垃圾收集器的性能。基准测试是衡量系统性能的重要手段,它能帮助开发者了解特定配置下GC的工作效率,以及不同GC算法对应用性能的影响。这个...