java会自动回收内存,但APP应用程序,特别是服务器程序最好根据业务情况指定内存分配限制。 APP应用程序可能会关闭。
举例说明意思:
-Xms128m米
JVM Heap (堆内存)最小大小128MB,表示初始分配
-Xmx512m米
表示JVM Heap (堆内存)的最大允许大小256MB,根据需要分配。
描述:如果未指定-Xmx或指定值很小,应用可能会导致java.lang.OutOfMemory错误。 此错误来自JVM,无法在try.catch中捕获,而不能在Throwable中捕获。
PermSize和MaxPermSize是虚拟机为Javapermanategeneration (例如class对象、method对象)等可反射对象分配内存限制,这些内存包含在Heap区域中
-XX:PermSize=64MB最小大小,初始分配
- xx :最大大小=256 MB最大允许大小,根据需要分配
如果太小,Java.lang.out of memory error 3360 permgenspace
MaxPermSize的缺省值与-server -client选项相关。
-server选项的缺省MaxPermSize为64m
-client选项的缺省MaxPermSize为32m
经验:
1、谨慎使用最小限制选项Xms,PermSize节约了系统资源。
=========================================================================================
在最近的研究中,为了监视jvm的内存使用情况,为了观察虚拟机的内存使用情况,进行了一些收集,了解了jvm的参数设定。
一些基本概念:
PermGen space :全名是Permanent Generation space或永久世代。 永久存储的区域,用于存储Class和元信息。 因为Class在加载时被放入那个区域,GC(garbagecollection )应该不清理PermGen space,所以如果你的APP加载很多Class,permgen就有可能出现
标题:保存实例。 Java Heap可分为Young即jjdmf世代、Old即老一代和Permanent个区。 Young保存刚实例化的对象。 当此区域填满时,GC会将对象移动到Old区域。 Permanent区域负责保存反射对象。
一些参数设置的含义:
xms/xmx :定义young old段的总大小。 ms是JVM启动时youngold的内存大小。 mx是qpdppx消耗最多的YOUNG OLD存储器大小。 在用户生产环境中,通常将这两个值设置为相同的值,以减少系统在运行过程中用于申请内存的开销。
new size/max new size :定义young段的大小。 newsize是JVM启动时young的内存大小。 MaxNewSize是qpdppx消耗最多的YOUNG内存大小。 在用户生产环境中,通常将这两个值设置为相同的值,以减少系统在运行过程中用于申请内存的开销。
permsize/maxperm size :定义perm段的大小。 permsize是JVM启动时perm的内存大小。 MaxPermSize是qpdppx消耗最多的Perm内存大小。 在用户生产环境中,通常将这两个值设置为相同的值,以减少系统在运行过程中用于申请内存的开销。
survivor ratio :设定young世代的survivor空间和bldll空间的比率
申请一块内存的过程:
A. JVM尝试初始化关联的Java对象的bldll中的内存区域
在bldll区域足够的情况下,存储器申请结束。 否则就进入下一步
C. JVM尝试释放bldll中所有非活动的对象。 (这属于一个或多个垃圾回收。 )如果释放后bldll区域仍不足以容纳新对象,请尝试将某些bldll中的活动对象放入Survivor区域/OLD区域
D. Survivor区域用作bldll和OLD的中间交换区域,如果OLD区域有足够的空间,Survivor区域中的对象将移动到OLD区域,否则将保留在Survivor区域中
如果e.OLD区空间不足,JVM将在old区进行完整的垃圾收集(0级) )。
f .如果JVM无法在bldll区域中创建新对象的内存区域,原因是垃圾回收完成后,从bldll复制的某些对象未保存在Survivor和OLD区域中,则会出现“out of memory错误”
我们的resin服务器的jvm参数设置:
“- xmx 2000 m-xms 2000 m-xmn 500 m-xx : permsize=250 m-xx : maxperm size=250 m-x ss256 k-xx 3360 disableexplicitgc -”
AtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSClassUnloadingEnabled -XX:LargePageSizeInBytes=128M -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=60 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+PrintClassHistogram -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Xloggc:log/gc.log”是一种典型的响应时间优先型的配置。
Java中有四种不同的回收算法,对应的启动参数为
–XX:+UseSerialGC
–XX:+UseParallelGC
–XX:+UseParallelOldGC
–XX:+UseConcMarkSweepGC
1. Serial Collector
大部分平台或者强制 java -client 默认会使用这种。
young generation算法 = serial
old generation算法 = serial (zsdej-sweep-compact)
这种方法的缺点很明显,stop-the-world, 速度慢。服务器应用不推荐使用。
2. Parallel Collector
在linux x64上默认是这种,其他平台要加 java -server 参数才会默认选用这种。
young = parallel,多个thread同时copy
old = zsdej-sweep-compact = 1
优点:jjdmf代回收更快。因为系统大部分时间做的gc都是jjdmf代的,这样提高了throughput(cpu用于非gc时间)
缺点:当运行在8G/16G server上old generation live object太多时候pause time过长
3. Parallel Compact Collector (ParallelOld)
young = parallel = 2
old = parallel,分成多个独立的单元,如果单元中live object少则回收,多则跳过
优点:old old generation上性能较 parallel 方式有提高
缺点:大部分server系统old generation内存占用会达到60%-80%, 没有那么多理想的单元live object很少方便迅速回收,同时compact方面开销比起parallel并没明显减少。
4. Concurent Mark-Sweep(CMS) Collector
young generation = parallel collector = 2
old = cms
同时不做 compact 操作。
优点:pause time会降低, pause敏感但CPU有空闲的场景需要建议使用策略4.
缺点:cpu占用过多,cpu密集型服务器不适合。另外碎片太多,每个object的存储都要通过链表连续跳n个地方,空间浪费问题也会增大。
内存监控的方法:
1. jmap -heap pid
查看java 堆(heap)使用情况
using thread-local object allocation.
Parallel GC with 4 thread(s) //GC 方式
Heap Configuration: //堆内存初始化配置
MinHeapFreeRatio=40 //对应jvm启动参数-XX:MinHeapFreeRatio设置JVM堆最小空闲比率(default 40)
MaxHeapFreeRatio=70 //对应jvm启动参数 -XX:MaxHeapFreeRatio设置JVM堆最大空闲比率(default 70)
MaxHeapSize=512.0MB //对应jvm启动参数-XX:MaxHeapSize=设置JVM堆的最大大小
NewSize = 1.0MB //对应jvm启动参数-XX:NewSize=设置JVM堆的‘jjdmf代’的默认大小
MaxNewSize =4095MB //对应jvm启动参数-XX:MaxNewSize=设置JVM堆的‘jjdmf代’的最大大小
OldSize = 4.0MB //对应jvm启动参数-XX:OldSize=<value>:设置JVM堆的‘老生代’的大小
NewRatio = 8 //对应jvm启动参数-XX:NewRatio=:‘jjdmf代’和‘老生代’的大小比率
SurvivorRatio = 8 //对应jvm启动参数-XX:SurvivorRatio=设置年轻代中bldll区与Survivor区的大小比值
PermSize= 16.0MB //对应jvm启动参数-XX:PermSize=<value>:设置JVM堆的‘永生代’的初始大小
MaxPermSize=64.0MB //对应jvm启动参数-XX:MaxPermSize=<value>:设置JVM堆的‘永生代’的最大大小
Heap Usage: //堆内存分步
PS Young Generation
bldll Space: //bldll区内存分布
capacity = 20381696 (19.4375MB) //bldll区总容量
used = 20370032 (19.426376342773438MB) //bldll区已使用
free = 11664 (0.0111236572265625MB) //bldll区剩余容量
99.94277218147106% used //bldll区使用比率
From Space: //其中一个Survivor区的内存分布
capacity = 8519680 (8.125MB)
used = 32768 (0.03125MB)
free = 8486912 (8.09375MB)
0.38461538461538464% used
To Space: //另一个Survivor区的内存分布
capacity = 9306112 (8.875MB)
used = 0 (0.0MB)
free = 9306112 (8.875MB)
0.0% used
PS Old Generation //当前的Old区内存分布
capacity = 366280704 (349.3125MB)
used = 322179848 (307.25464630126953MB)
free = 44100856 (42.05785369873047MB)
87.95982001825573% used
PS Perm Generation //当前的 “永生代” 内存分布
capacity = 32243712 (30.75MB)
used = 28918584 (27.57891082763672MB)
free = 3325128 (3.1710891723632812MB)
89.68751488662348% used