来源:http://liuxuan.info/blog/2011/04/03/jvm-memory-management-and-gc/
一.Java基本类型和类的大小
1.Java手册上的类型大小
byte : 8-bit
short : 16-bit
Int : 32-bit
long : 64-bit
char : 16 bit unsigned integer
float : 32-bit
double: 64-bit
boolean: 1-bit
2.实际存储大小(根据JVM实现而定)
Byte : 16 bytes
Short : 16 bytes
Integer : 16 bytes
Long : 16 bytes
Character : 16 bytes
Float : 16 bytes
Double : 16 bytes
Boolean : 16 bytes
Object :8 bytes
二.JVM的堆结构
运行时数据区域,所有类实例和数组的内存均从此处分配,由Java 虚拟机启动时创建。对象的堆内存由称为垃圾回收器的自动内存管理系统回收。
堆由两部分组成:
Eden+From Space+To Space也叫做Young Generation(年轻代),Tenured Space也叫做Old Generation(老年代)。
Survivor Space包括S0和S1。
Permanent Space(方法区): JVM具有一个由所有线程共享的方法区。它存储每个类结构,如运行时常数池、字段和方法数据,以及方法和构造方法的代码,它是在Java虚拟机启动时创建的,不包括在JVM堆内,默认为4M。
这个区域主要存放:
1.Class的信息
包名
父类的包名
类或接口
类型修饰符
父接口包名
2.其它信息
类型的常量池
属性
方法
类里的静态变量(除了常量)
一个指向ClassLoader的引用
一个指向Class类的引用
三.GC的工作流程
绝大多数情况下对象初始化被分配在Eden中(一个非常大的对象会被分配在老年代中)。
如果Eden空间占满了, 会触发 minor GC。 Minor GC 后仍然存活的对象会被复制到S0中去。这样Eden就被清空可以分配给新的对象。
又触发了一次 Minor GC , S0和Eden中存活的对象被复制到S1中, 并且S0和Eden被清空。 在同一时刻, 只有Eden和一个Survivor Space同时被操作。
当每次对象从Eden复制到Survivor Space或者从Survivor Space中的一个复制到另外一个,有一个计数器会自动增加值。 默认情况下如果复制发生超过16次, JVM 会停止复制并把他们移到老年代中去。
如果一个对象不能在Eden中被创建,它会直接被创建在老年代中。 如果老年代的空间被占满会触发老年代的 GC,也被称为 Full GC。full GC 是一个压缩处理过程,所以它比Minor GC要慢很多。
四.GC算法
Serial Collector
大部分平台或者强制java -client默认会使用这种。 Young Generation = Serial Old Generation = Serial (Mark-Sweep-Compact) 这种方法的缺点很明显,Stop-the-world, 速度慢。服务器应用不推荐使用。
Parallel Collector
在Linux x64上默认是这种算法,其他平台要加java -server参数。 Young Generation = parallel,多个thread同时copy Old Generation = Mark-Sweep-Compact = 1 优点:新生代回收更快。因为系统大部分时间做的GC都是新生代的,这样提高了Throughput(CPU用于非GC时间)。 缺点:当运行在8G/16G Server 上 Old Generation 存活对象太多的时候暂停时间(Pause Time)过长。
Parallel Compacting Collector (ParallelOld)
Young Generation = parallel Old Generation = parallel 优点:Old Generation 上性能较 Parallel Collector 方式有提高。 缺点:大部分Server系统Old Generation内存占用会达到60%-80%, Compact方面开销比起Parallel Collector并没明显减少。
Concurent Mark-Sweep(CMS) Collector (low-latency collector)
Young Generation = parallel Old Generation = CMS 同时不做 compact 操作。 优点:Pause Time会降低, Pause Time敏感但CPU有空闲的场景需要建议使用策略4。 缺点:CPU占用过多,CPU密集型服务器不适合。需要更大的堆空间,会造成很多碎片。
五.JVM的默认设置
1.堆(heap)即(New Generation 和Old Generaion 之和)的设置
初始分配的内存由-Xms指定,默认是物理内存的1/64但小于1G。
最大分配的内存由-Xmx指定,默认是物理内存的1/4但小于1G。
默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制,可以由-XX:MinHeapFreeRatio指定。
默认空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制,可以由-XX:MaxHeapFreeRatio指定。
服务器一般设置-Xms、-Xmx相等以避免在每次GC后调整堆的大小,所以上面的两个参数没啥用。
-Xmn设置Young Generation的heap大小
-XX:MinHeapFreeRatio与-XX:MaxHeapFreeRatio设定空闲内存占总内存的比例范围,这两个参数会影响GC的频率和单次GC的耗时。-XX:NewRatio决定Young与Old Generation的比例。Young generation空间越大,Minor GC频率越低,但是Old Generation空间小了,又可能导致Major GC频率增加。-XX:NewSize和-XX:MaxNewSize直接指定了Young Generation的缺省大小和最大大小。
2.非堆内存的设置
默认分配为64M
-XX:PermSize设置最小分配空间,-XX:MaxPermSize设置最大分配空间。一般把这两个数值设为相同,以减少申请内存空间的时间。
六.GC调优
参考:GC调优例子
设置Xms=Xmx=3/4物理内存,-Xmn为1/4的-Xmx值
如果是CPU密集型服务器,使用–XX:+UseParallelOldGC, 否则–XX:+UseConcMarkSweepGC
新生代,Parallel/ParallelOld可设大于Xmx1/4,CMS可设小,小于Xmx1/4
经验之谈:通常情况下,JVM堆的大小应为物理内存的80%
七.Dump heap
1.Linux下:jmap -dump:file=xxx.hprof pid,其中pid通过ps -aux命令查看
2.命令行:jstat -gcutil pid p1 p2,其中p1表示每多少毫秒打印一次;p2表示一共打印几次。
输出的参数含义:
S0:Heap上的 Survivor space 0 段已使用空间的百分比
S1:Heap上的 Survivor space 1 段已使用空间的百分比
E: Heap上的 Eden space 段已使用空间的百分比
O: Heap上的 Old space 段已使用空间的百分比
P: Perm space 已使用空间的百分比
YGC:从程序启动到采样时发生Young GC的次数
YGCT:Young GC所用的时间(单位秒)
FGC:从程序启动到采样时发生Full GC的次数
FGCT:Full GC所用的时间(单位秒)
GCT:用于垃圾回收的总时间(单位秒)
jstat 命令其他参数含义:
jstat -class pid:显示加载class的数量,及所占空间等信息。
jstat -compiler pid:显示VM实时编译的数量等信息。
jstat -gc pid:可以显示gc的信息,查看gc的次数,及时间。其中最后五项,分别是young gc的次数,young gc的时间,full gc的次数,full gc的时间,gc的总时间。
jstat -gccapacity:可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小,如:PGCMN显示的是最小perm的内存使用量,PGCMX显示的是perm的内存最大使用量,PGC是当前新生成的perm内存占用量,PC是但前perm内存占用量。其他的可以根据这个类推, OC是old内纯的占用量。
jstat -gcnew pid:new对象的信息。
jstat -gcnewcapacity pid:new对象的信息及其占用量。
jstat -gcold pid:old对象的信息。
jstat -gcoldcapacity pid:old对象的信息及其占用量。
jstat -gcpermcapacity pid: perm对象的信息及其占用量。
jstat -util pid:统计gc信息统计。
jstat -printcompilation pid:当前VM执行的信息。
3.GC Log
-Xloggc:d:\gc.log -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps – add time stamp
八.Out of Memory - java.lang.OutOfMemoryError
1.Java heap space
Configuration issue: -Xmx
Memory Leak: The excessive use of finalizers
PermGen space: Too many classes-XX:MaxPermSize
Requested array size exceeds VM limit: Need a so big array?
Request bytes for : Out of swap space?
Native Memory Leak
(Native method)
Native Memory Allocation Issue
2.Perm Memory Leak
(1)Too Many Interned String
String.intern()
Constant String will be interned implicitly
No Enough Info provided by Heap Dump on Interned String
If Perm Memory increased dynamically, be careful
(2)Too Many Classes or Class Load Leak
Enlarge the perm generation
Avoid duplicated class loader
3.Out of Swap Space
Enlarge the swap space
Systems with 4GB of ram or less require a minimum of 2GB of swap space
Systems with 4GB to 16GB of ram require a minimum of 4GB of swap space
For Unix Family OS, use pmdump or pmap, libumem for Solaris
分享到:
相关推荐
最后,文档还提供了更多资源链接,供感兴趣的读者深入了解JVM内存管理和垃圾收集。 从这些核心内容可以看出,《JVM内存管理白皮书》是JVM内存管理领域的权威资料。它不仅向读者提供了JVM垃圾收集机制的理论知识,还...
jvm--java毕业设计-JVM内存模型和垃圾收集PPT37页--JVM内存模型和垃圾收集
通过以上内容可以看出,深入理解JVM内存管理和垃圾收集机制对于提高应用程序的性能至关重要。尽管现代JVM已经非常智能,能够自动管理大部分内存相关的工作,但在面对复杂的应用场景时,仍然需要开发人员具备一定的...
本文将基于“JVM内存模型和垃圾收集”的主题,深入探讨JVM中的内存管理机制以及垃圾收集的相关技术细节。 #### 二、JVM内存模型概述 JVM内存模型主要涉及以下几个关键概念: 1. **堆(Heap)** - **定义**:堆是...
Java 堆也是垃圾收集器管理的主要区域,如果从内存回收的角度看,由于现在收集器采用分代收集算法所以可以分为老年代和新生代,再细致有 Eden 空间、from 空间、to 空间,但是无论怎么划分,它都是只是存储对象实例...
总的来说,理解和掌握JVM内存模型及垃圾收集策略对于优化Java应用程序的性能至关重要。开发者需要根据应用特点调整内存参数,选择合适的垃圾收集策略,以避免内存溢出、提高系统效率并确保程序的稳定运行。
理解JVM内存管理和垃圾回收机制对于优化Java应用程序性能至关重要,开发者可以通过调整JVM参数来定制适合应用需求的内存配置和垃圾回收策略。例如,设置新生代和老年代的大小、选择合适的垃圾回收器、设定最大暂停...
在深入理解JVM内存管理和垃圾收集器之前,我们需要先了解JVM内存模型的基本结构。 内存模型主要包括以下几个部分: 1. **Java堆**:这是JVM管理的最大的内存区域,所有线程共享,主要用于存储类实例和数组。堆内存...
在深入理解JVM内存模型与垃圾收集策略之前,我们首先需要知道JVM的主要组成部分:类装载器、运行数据区、执行引擎、本地方法接口和本地方法库。 1. **JVM内存模型** JVM内存主要分为以下几个区域: - **程序...
JVM内存模型与垃圾回收是...总的来说,理解JVM内存模型和垃圾回收机制对于优化Java应用性能至关重要,它涉及到内存分配策略、垃圾收集算法的选择以及内存参数的调整,这些都需要开发者具备深入的JVM知识和实践经验。
JVM内存管理是Java平台的一个重要特性,其内存空间的分配和回收机制对Java应用程序的性能和稳定性有着至关重要的影响。 首先,JVM内存管理涉及的内存空间主要分为方法区(Method Area)、堆(Heap)、本地方法栈...
Java虚拟机(JVM)内存管理和垃圾回收是Java编程中至关重要的概念,它涉及到程序的性能和稳定性。本文主要探讨了JVM如何处理内存分配、垃圾检测与回收,以及各种策略和性能指标。 首先,垃圾回收是JVM的一项核心...
Java虚拟机(JVM)是Java程序的核心组成部分,它负责执行字节码并管理内存。在JVM的学习中,理解其内存模型...在实际开发中,理解JVM的工作原理对于解决内存问题、选择合适的垃圾收集器和调整内存配置都具有重要意义。
Java虚拟机(JVM)内存管理和...总结来说,JVM内存管理和垃圾回收是一个复杂而精细的过程,涉及多种策略和算法,旨在高效利用内存,减少应用暂停时间,并防止内存泄漏。理解和掌握这些原理对优化Java应用性能至关重要。
第二节:JVM内存模型 1.1 概念 1.2 JVM内存模型 1.3 Heap堆内存模型 第三节:定位垃圾对象的依据 1.1 引用计数法 1.2 可达性算法 第四节:垃圾回收算法 1.1标记清除算法 1.2复制算法 1.3 标记整理(标记压缩)...
很久之前就一直在学习JVM,但是一直也没有好好的总结,最近终于有了空闲,将之前学习的内容整理成了一个PPT。 也希望大神们可以批评指正。 ppt中主要包含下面几部分: Java内存模型 ... 垃圾收集器
Java虚拟机(JVM)是Java程序运行的核心,它负责管理程序的内存,包括线程共享的堆内存、线程私有的虚拟机栈、...了解这些JVM内存管理和垃圾收集的知识,有助于优化Java应用程序的性能,减少内存泄漏和提高系统稳定性。
JVM内存管理是Java虚拟机的核心机制之一,其主要包含对象的创建、内存分配、...通过对内存分配策略、对象生死判定、垃圾收集算法和垃圾收集器的理解与应用,可以更好地掌握JVM的内存管理,从而提升应用性能和稳定性。
Java垃圾收集调优是优化Tomcat性能的关键环节,主要涉及JVM内存管理和垃圾收集机制。在Tomcat中,我们可以通过调整JVM参数来优化内存分配和垃圾收集行为,以提高应用的响应速度和稳定性。 首先,JVM内存分为三个...