一.运行时数据区:
- 程序计数器:它是一块较小的内存空间,主要作用是当前线程所执行的字节码的行号指示器.由于java虚拟机的多线程是通过轮流切换并分配处理器执行时间的方式来实现的(协作式/抢占式?!),即任何时刻,任一CPU只会正在处理一个线程的指令;为了确保线程切换后能够正确恢复执行的位置,每个线程都有一个独立的程序计数器,每个计数器为线程私有.如果线程正在执行java方法,那么此计数器记录的是正在执行的字节码指令地址;如果执行的是Native方法,那么它(计数器)的值则为undefined.
- 虚拟机栈:线程私有,每个线程在执行java方法时都会被创建虚拟机栈,它用来存储方法执行期间的局部变量/操作数栈/动态连接表等.直到方法退出.局部变量表存放了编译期可知的各种基本类型(boolean,int,char...)以及对象引用类型(reference).如果线程请求的栈深度大于JVM所允许的深度,将会抛出statckOverflowError.
- 本地方法栈:对于native方法调用期间,jvm为线程创建的空间.在hotspot中,本地方法栈和虚拟机栈合二为一.
- 堆:JVM规范中阐述,所有的对象都将被存储在堆中;堆有可以根据对象的生命周期和收集策略,分为新生代和旧生代;其中新生代中为了便于GC和性能优化,再次分为Eden,from/to交换区三个小区.
- 方法区:通常称为持久带(hotspot JVM中持久带即为“方法区”的实现,位于堆中),此区为线程共享区域;用于存储VM加载的类信息/常量/静态变量等,它作为堆的逻辑部分,但在GC和空间使用上和堆有着很大的不同.方法区一般很少会被GC,但是方法区中的常量池以及类引用的卸载,仍然会被GC;当方法区空间不足时,仍会抛出OOM异常.(在JAVA 8中,已经不再有持有带,取而代之的是一个称为“元空间”--Metaspace的概念,它在堆之外,并为系统的直接内存)
- 运行时常量池:作为方法区的一部分,用于编译期生成的各种字面量和符号引用,它具有动态性,即在运行时仍然可以讲常量添加到常量池中,例如String.intern()方法.常量池会被GC.
- 直接内存(Directed Menory):通常发生在NIO中为了提升性能,将生命周期较长的buffer声明为直接内存,直接内存不会受到heap区域大小的限制(--Xms,--Xmx参数对其无效),直接内存的大小受到本机物理内存和OS-swap区域大小的限制,如果无法申请到直接内存,JVM也将抛出OOM异常.
JVM采取了"直接内存指针"方式来访问对象,即本地变量表中维护的对象reference直接指向对象数据的内存地址,在此对象数据中包含了此对象类型的引用(Class),此方式对于操作对象更加快捷.
二.JVM常用调优/调试参数:
-Xms<size> |
例如:-Xms2G,设置Heap的初始大小 |
-Xmx<size> |
设置Heap的最大尺寸,建议为最大物理内存的1/3(建议此值不超过12G) |
-Xss<size> |
方法栈大小 |
-Xmn<size> |
新生代大小 |
-XX:NewSize=<value> -XX:MaxNewSize=<value> -XX:SurvivorRatio=<value> |
新生代设置.单位为byte SurvivorRatio = Eden/survivor;例如此值为3,则表示,Eden : from : to = 3:1:1;默认值为8 |
-XX:PermSize=<value> -XX:MaxPermSize=<value> |
方法区大小,max值默认为64M |
-XX:[+ | -]UseConcMarkSweepGC |
打开或关闭基于ParNew + CMS + SerialOld的收集器组合.(-XX:+UseParNewGC) |
-XX:[+ | -]UseParallelGC |
在server模式下的默认值(+),表示使用Parallel Scavenge + Serial Old收集器组合 |
-XX:[+ | -]UseParallelOldGC |
默认关闭,+表示打开/使用Parallel Scavenge + Parallel Old收集器组合 |
-XX:PretenureSizeThreshold=<value> |
直接晋升为旧生代的对象大小.大于此值的将会直接被分配到旧生代,单位byte |
-XX:MaxTenuringThreshold=<value> |
晋升到旧生代的对象年龄(已经或者即将被回收的次数);每个对象被minor GC一次,它的年龄+1,如果对象的年龄达到此值,将会进入旧生代. |
-XX:[+ | -]UseAdaptiveSizePolicy |
默认开启;是否动态调整java中堆中各个区域大小以及进入旧生代的年龄;此参数可以方便我们对参数调优,找到最终适合配置的参数. |
-XX:[+ | -]HandlePromotionFailure |
JDK1.6默认开启,是否支持内存分配失败担保策略;在发生Minor GC时,虚拟机会检测之前每次晋升到老年代的平均大小是否大于老年代的剩余空间大小,如果大于,则改为直接进行一次Full GC。如果小于,则查看HandlePromotionFailure设置是否允许担保失败;如果允许,那只会进行Minor GC;如果不允许,则也要改为进行一次Full GC。 |
-XX:ParallelGCThreads=<value> |
并行GC时所使用的线程个数.建议保持默认值(和CPU个数有换算关系). |
-XX:GCTimeRatio=<value> |
GC占JVM服务总时间比.默认为99,即允许1%的GC时间消耗.此参数只在Parallel Scavenge收集器下生效 |
-XX:CMSInitiatingOccupancyFraction=<value> |
设置CMS收集器在旧生代空间使用占比达到此值时,触发GC. |
-XX:[+ | -]UseCMSCompactAtFullCollection |
默认开启,表示在CMS收集器进行一次Full gc后是否进行一次内存碎片整理,[原因:CMS回收器会带来内存碎片] |
-XX:CMSFullGCSBeforeCompaction=<value> |
进行多少次FullGC之后,进行一次内存碎片整理.[原因:CMS回收器会带来内存碎片] |
我们可以通过使用“java -XX:+PrintFlagsFinal -version”打印JVM中可选参数以及其默认值。
还有其他的可选参数:
1)-XX:NewRatio=4:表示新生代与老年代的比例,其中不包含持久带,比如NewRatio=4,表示新生代与老年代的比为1:4;对于JVM而言,-XX:NewSize和-XX:MaxNewSize将首先生效并覆盖NewRatio。
2)-XX:MaxMetaspaceSize=512M:JDK 8新增的参数,因为JDK 8不再有“perm”区,原来持久带改称为“Metaspace”,通过压缩保存在操作系统的直接内存中。
参考样例:
JAVA_OPTS = "-verbose:gc
-Xms3G -Xmx=3G
-XX:MaxPermSize=256M
-XX:SurvivorRatio=3
-XX:MaxNewSize=1G
-XX:+UseConcMarkSweepGC
-XX:MaxTenuringThreshold=5
-XX:CMSInitiatingOccupancyFraction=70
-XX:+UseCMSCompactAtFullCollection
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:../logs/server-gc.log.$(date +%Y%m%d%H%M)
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=1
-XX:GCLogFileSize=512M"
JVM性能工具推荐:jclarity,非开源,分析JVM性能、GC日志分析和调优建议,非常好用!
相关推荐
总结,Java JVM内存分配和调优是一项复杂的任务,需要结合实际应用的需求和性能指标来调整。通过理解JVM内存模型,选择合适的垃圾收集器和设置合理的内存参数,可以有效提升Java应用的性能和稳定性。在实践中,不断...
2. JVM内存模型:JVM内存模型定义了内存中各个部分的关系,以及在多线程环境下如何共享和分配内存。Java内存模型(JMM)规定了线程对共享变量的可见性和有序性,它通过主内存和工作内存的概念来实现多线程之间的协作...
JVM内存设置与调优是提升应用性能的关键环节,对于大型系统尤其重要。本指南将深入探讨JVM内存模型,以及如何通过调整相关参数来优化性能。 首先,我们需要理解JVM的内存结构。JVM内存主要分为以下几个区域: 1. *...
**JVM内存管理及调优** Java虚拟机(JVM)是Java程序运行的基础,它为Java应用程序提供了运行环境。JVM内存管理是优化Java应用性能的关键环节,涉及到内存分配、垃圾回收以及内存溢出等问题。毕玄,一位在淘宝有着...
总的来说,JVM内存管理、调优与监控是一项综合性的技术工作,需要对JVM内部机制有深入理解,并结合具体应用场景进行细致的分析和实践。由于JVM的实现可能存在差异,且规范与实现之间存在一定的不一致性,因此,进行...
理解GC工作原理有助于优化内存分配和减少垃圾收集的开销。 【JVM调优实践】 JVM调优包括选择合适的垃圾收集器、调整堆大小、设置新生代与老年代的比例、控制并发比等。例如,PS(Parallel Scavenge)和PO(Parallel...
在这个资源中,我们将详细讨论 JVM 内存参数的配置和调优,包括 JVM 的结构、内存管理、垃圾回收、堆和非堆内存、内存分配和限制等方面。 JVM 结构 JVM 的结构主要由六个部分组成:JVM API、JVM 内部组件、平台...
### JVM内存空间分配详解 #### 一、JVM内存模型概览 ...综上所述,理解JVM内存分配机制对于Java开发者来说至关重要,这不仅有助于编写高效、稳定的代码,还能在遇到性能瓶颈时快速定位问题并进行优化。
JVM参数调优部分未在提供的内容中显示,但一般来说,JVM参数调优会涉及到调整堆内存分配、堆外内存大小、垃圾回收器选择、新生代和老年代的比例,以及各种相关参数如-Xms、-Xmx、-Xmn、-XX:+UseG1GC等。这些调整能...
1. JVM内存分配与回收 在JVM中,内存分为新生代、老年代和持久代。新生代又细分为Eden区和两个Survivor区。对象优先在Eden区分配,这是因为大部分对象生命周期短,快速创建和销毁。当Eden区满时,会触发Minor GC,...
【标题】"Tomcat JVM参数调优...总的来说,JVM参数调优是一个涉及内存分配、垃圾回收效率和系统资源平衡的复杂过程。适当的调优能确保Tomcat在处理大量并发请求时保持高效和稳定,同时避免内存问题导致的服务中断。
JVM参数调优是优化Java应用程序性能的关键环节,尤其是在服务器端的应用中,如Web服务器Resin。本实践案例中,作者分别尝试了三种不同的垃圾回收(GC)策略:串行回收、并行回收和并发回收,并针对每种策略提供了...
合理设置和调优JVM内存参数,是提高Java应用性能的关键所在。通过对JVM内存管理机制的理解,结合具体的应用场景,开发者可以有效地避免内存溢出错误,确保应用稳定高效地运行。希望本文能为您的Java项目提供有力的...
本文将围绕JVM调优展开讨论,重点分析数据类型、堆与栈的关系及其对程序性能的影响,并探讨Java中的参数传递机制。 #### 二、数据类型 在Java虚拟机中,数据类型分为两大类:基本类型和引用类型。 - **基本类型**...
- `jmap`:获取堆内存快照,分析内存分配。 - `jhat`:分析`jmap`导出的内存转储文件。 - `jstack`:查看线程堆栈信息,诊断死锁或线程阻塞问题。 - `jinfo`:获取JVM配置信息。 - `jcmd`:JDK 8新增的命令行...
本资料总结主要关注JVM内存分配及其运行原理,这对于理解和优化Java应用程序的性能至关重要。 1. **JVM内存结构** JVM内存分为几个关键区域:方法区(Method Area)、堆(Heap)、栈(Stack)、程序计数器(PC ...
这些参数可以调整JVM的行为,如内存分配、垃圾收集策略、编译器行为等。 1. **堆内存设置**:如-Xms和-Xmx分别设置初始堆大小和最大堆大小,确保合适的内存分配避免OutOfMemoryError。 2. **新生代和老年代内存...
6. **JVM内存溢出问题** - 常见的内存溢出错误有OOM(Out Of Memory),如堆溢出、 PermGen/Metaspace 溢出等,需要通过调整内存大小或优化代码来解决。 7. **JIT编译器** - JVM包含解释器和JIT(Just-In-Time)...