----------~开篇分享一句话:【纸上得来终觉浅,绝知此事要躬行】~---------------------------------------
实战分析:
http://wangxinchun.iteye.com/blog/2190330
http://www.360doc.com/content/14/0508/18/11965070_375867925.shtml
http://www.cnblogs.com/dingyingsi/p/3760447.html
jvm的组成:
java内存组成:堆(Heap)和非堆(Non-heap)内存
按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。可以看出JVM主要管理两种类型的内存:堆和非堆。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给 自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法 的代码都在非堆内存中。
jvm 内存的构成:
方法栈&本地方法栈:线程创建时产生,方法执行时生成栈帧 永久代(方法区):存储类的元数据信息 常量等 堆(heap):java代码中所有的new操作 native Memory(C heap) Direct Bytebuffer JNI Compile GC;
JVM体系结构
JVM运行时数据区
共享内存区
JVM运行时内存 = 共享内存区 + 线程内存区
共享内存区 = 持久带 + 堆
持久带 = 方法区 + 其他
堆 = Old Space + Young Space
Young Space = Eden + S0 + S1
堆内存分配:
JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指 定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。对象的堆内存由称为垃圾回收器的自动内存管理系统回收。
Young Generation:Eden + From Space + To Space
Eden:存放新生的对象
Survivor Space:有两个,存放每次垃圾回收后存活的对象
Old Generation:主要存放应用程序中生命周期长的存活对象
非堆内存分配:
JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。
Permanent Generation:
1、保存虚拟机自己的静态(refective)数据
2、主要存放加载的Class类级别静态对象如class本身,method,field等等
3、permanent generation空间不足会引发full GC
直接内存:
直接内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError 异常出现。应用在某些场景中能显著提高性能,因为其避免了在Java堆和Native堆中来回复制数据。
显然,本机直接内存的分配不会受到Java 堆大小的限制,但是,既然是内存,则肯定还是会受到本机总内存(包括RAM 及SWAP 区或者分页文件)的大小及处理器寻址空间的限制。服务器管理员配置虚拟机参数时,一般会根据实际内存设置-Xmx等参数信息,但经常会忽略掉直接内存,使得各个内存区域的总和大于物理内存限制(包括物理上的和操作系统级的限制),从而导致动态扩展时出现OutOfMemoryError异常。
Jvm Stack(java虚拟机栈):不在堆区
Local Method Statck(本地方法栈)
JVM内存限制(最大值)
32位 最大为4G,64位无限制
jvm参数:
-Xmx3550m:设置JVM最大可用内存为3550M。
-Xms3550m:设置JVM初使内存为3550m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
-Xmn2G:设置年轻代大小为2G。
-Xss1M: 设置线程堆栈的大小,和方法调用的深度以及StackOverFlowError有密切关系
XX:NewRatio=4,设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5
注意:一般情况下XX:NewRatio 和 -Xmn 不同时设置
-XX:SurvivorRatio=4:设置年轻代中Eden区与一个Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6
-XX:MaxPermSize=16m:设置持久代大小为16m。
-XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概率。
注意:
整个JVM内存大小=年轻代大小 + 年老代大小
年老代大小 = Xmx-Xmn
JVM 参数默认值:
-Xms 默认情况下堆内存的64分之一
-Xmx 默认情况下对内存的4分之一
-Xmn 默认情况下堆内存的64分之一
-Xss 一个线程的占用内存大小,方法调用的深度
-XX:NewRatio 默认为2
-XX:SurvivorRatio 默认为8
-XX:-OmitStackTraceInFastThrow :始终打印 异常错误信息,否则:很多行的java.lang.NullPointerException 苦于找不到stacktrace而不知道错误出在何处。
-XX:+DisableExplicitGC:这个参数作用是禁止代码中显示调用GC。代码如何显示调用GC呢,通过System.gc()函数调用。如果加上了这个JVM启动参数,那么代码中调用System.gc()没有任何效果,相当于是没有这行代码一样。
-verbose:gc: -XX:+PrintGC 与 -verbose:gc 是一样的,可以认为-verbose:gc 是 -XX:+PrintGC的别名.
参数-XX:+PrintGC(或者-verbose:gc)开启了简单GC日志模式,为每一次新生代(young generation)的GC和每一次的Full GC打印一行信息。下面举例说明:
[GC 246656K->243120K(376320K), 0.0929090 secs] [Full GC 243120K->241951K(629760K), 1.5589690 secs]简单模式的GC日志格式是与GC算法无关的,日志也没有提供太多的信息。在上面的例子中,我们甚至无法从日志中判断是否GC将一些对象从young generation移到了old generation。所以详细模式的GC日志更有用一些。
-XX:+PrintGCDateStamps: -XX:+PrintGCTimeStamps,这个选项记录的是jvm启动时间为起点的相对时间,可读性较差,不利于定位问题,使用PrintGCDateStamps记录的是系统时间,更humanreadable
-XX:+PrintGCDetails :打印gc日志的详细信息
[GC [PSYoungGen: 142816K->10752K(142848K)] 246648K->243136K(375296K), 0.0935090 secs] [Times: user=0.55 sys=0.10, real=0.09 secs]
这是一次在young generation中的GC,它将已使用的堆空间从246648K减少到了243136K,用时0.0935090秒。此外我们还可以得到更多的信息:所使用的垃圾收集器(即PSYoungGen)、young generation的大小和使用情况(在这个例子中“PSYoungGen”垃圾收集器将young generation所使用的堆空间从142816K减少到10752K)。
既然我们已经知道了young generation的大小,所以很容易判定发生了GC,因为young generation无法分配更多的对象空间:已经使用了142848K中的142816K。我们可以进一步得出结论,多数从young generation移除的对象仍然在堆空间中,只是被移到了old generation:通过对比绿色的和蓝色的部分可以发现即使young generation几乎被完全清空(从142816K减少到10752K),但是所占用的堆空间仍然基本相同(从246648K到243136K)。
详细日志的“Times”部分包含了GC所使用的CPU时间信息,分别为操作系统的用户空间和系统空间所使用的时间。同时,它显示了GC运行的“真实”时间(0.09秒是0.0929090秒的近似值)。如果CPU时间(译者注:0.55秒+0.10秒)明显多于”真实“时间(译者注:0.09秒),我们可以得出结论:GC使用了多线程运行。这样的话CPU时间就是所有GC线程所花费的CPU时间的总和。实际上我们的例子中的垃圾收集器使用了8个线程。
-Xloggc: /home/qddd/www/ddd/logs/gc.log: 指定gd日志打印的位置
-XX:+HeapDumpOnOutOfMemoryError:可以在内存的溢出的时候,输出hprof文件
并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。
并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),用户程序继续运行,而垃圾收集程序运行于另一个CPU上。
GC的时机:
YGC:eden空间不足
FGC:
1、old空间不足
2、perm空间不足
3、显示调用System.gc() ,包括RMI等的定时触发
-----------------------------------------------------------------------------------
内存模型:http://www.cnblogs.com/redcreen/archive/2011/05/04/2036387.html
调优:http://unixboy.iteye.com/blog/174173
参数设置:http://www.jvmer.com/jvm-xx-%E5%8F%82%E6%95%B0%E4%BB%8B%E7%BB%8D/
垃圾回收器:http://www.cnblogs.com/redcreen/archive/2011/05/04/2037029.html
内存申请步骤:http://www.cnblogs.com/redcreen/archive/2011/05/04/2037056.html
相关推荐
3. 不稳定参数(不稳定参数):以“-XX”开头,这些是非标准化参数,主要用于JVM调优和Debug。它们可以开启或关闭某些特性,或者对某些特性设置具体的数值。例如,“-XX:+UseConcMarkSweepGC”用于启用CMS垃圾回收器...
【JVM调优实战经验】 在Java开发中,JVM(Java Virtual Machine)的调优是提高应用程序性能的关键环节。JVM调优涉及到对内存管理、垃圾回收机制以及相关参数的调整,以优化应用程序的运行效率和稳定性。本文将深入...
《JVM调优实战》是一份深入探讨Java虚拟机(JVM)性能优化的文档,主要分为理论篇和实战篇两大部分。本文将详细解析其中的关键知识点。 理论篇首先介绍了JVM内存模型,将其比喻为一个多功能的养鱼塘。在这个比喻中...
分布式、并发和JVM调优是Java开发中的关键领域,对于构建高性能、可扩展的系统至关重要。在这篇文章中,我们将深入探讨这些主题,并基于提供的压缩包"Poet.zip"进行详细解析。 首先,我们来看看分布式系统。分布式...
本篇文章将详细讲解"JVM调优总结(4)分代垃圾回收"这一主题,旨在帮助Java开发者掌握更加高效、稳定的应用运行策略。 一、分代垃圾回收理论基础 Java的内存管理主要依靠垃圾回收机制,它自动回收不再使用的对象,...
本篇文章将依据"itcast-jvm.zip"压缩包中的实例,深入探讨JVM调优的关键知识点,帮助开发者提升应用性能,降低系统资源消耗。 一、JVM内存模型 JVM内存分为堆内存(Heap)、虚拟机栈(Java Stack)、本地方法栈...
本篇文章将基于提供的文件标题、描述以及部分链接信息来构建一系列关于JVM的核心知识点。 ### JVM基础知识 1. **什么是JVM**:Java虚拟机(Java Virtual Machine,简称JVM)是一种用于执行Java字节码的虚拟机。它...
4. JVM性能监测及调优:深入JVM,关注对象创建、回收和内存分配,以提升JVM效率。 5. 设计模式调优:结合实际场景,展示如何利用设计模式优化架构。 6. 数据库性能调优:讲解数据库调优技术,解决可能导致性能瓶颈的...
文档"深入Java虚拟机(原书第2版).pdf"将为你提供更深入的理论基础,"jvm优化.docx"涵盖了具体的JVM调优技巧,而"tomcat性能调优.docx"则专注于Tomcat的优化实践。通过学习这些资料,你将能够更好地理解和优化你的...
总的来说,这篇笔记深入介绍了JVM的内存管理,特别是垃圾收集机制,提供了从理论到实践的全面理解,对于Java开发者优化应用性能和理解JVM内部运作具有重要意义。通过掌握GC的触发时机、日志分析和优化策略,开发者...
JVM调优包括参数设置、性能监控和问题排查等。常见的JVM启动参数如-Xms、-Xmx控制堆内存大小,-XX:+UseConcMarkSweepGC选择垃圾收集器。通过JConsole、VisualVM等工具可以实时监控JVM状态,分析CPU、内存、线程等...
JVM调优是一个复杂的过程,涉及到对JVM配置参数的理解与调整。以下是一些常用的JVM监控与诊断工具: 1. **jps**:显示当前所有Java进程的信息。 2. **jinfo**:查询或更改JVM的配置参数。 3. **jstat**:查看JVM的...
本篇内容将深入探讨Java基础中的JVM初步使用,帮助你更好地理解Java程序在运行时的内部机制。 首先,我们需要了解JVM是什么。JVM是Java Virtual Machine的缩写,它是Java语言的一个关键组成部分,它是一个虚构的...
本篇文章详细介绍了WebLogic Server性能调优的相关理论知识,并结合实战案例进行了深入剖析,希望能为广大技术人员提供有价值的参考和帮助。在实践中,还需要不断学习新技术和新方法,以应对日益复杂的业务挑战。
JVM(Java Virtual ...总的来说,"JVM01-课程介绍1"是一门全面而深入的JVM教程,旨在帮助学习者建立扎实的JVM理论基础,掌握性能分析和问题排查技巧,以及积累实战经验,从而提升在Java开发和运维领域的专业能力。
本篇将从Java语言基础出发,逐步深入到JVM的学习路径,帮助你理解这一核心概念。 1. **Java语言简述** Java是一种面向对象的高级编程语言,它具有跨平台的特性,使得“Write Once, Run Anywhere”成为可能。编程...
《Sun_JDK_1.6内存管理--实现篇-毕玄.pdf》和《Sun_JDK_1.6内存管理--调优篇-毕玄.pdf》提供了宝贵的参考资料。 8. 实战优化 了解理论知识后,我们需要在实际项目中运用。《Sun_JDK_1.6内存管理--使用篇-毕玄.pdf...