包括:
一.JVM堆内存分配
二.JVM非堆内存分配
三.利用上述所学配置更快的Eclipse
一.JVM堆内存分配
1.1:JVM堆内存分配
JVM堆初始分配内存由-Xms指定,默认为物理内存的1/64,当默认堆内存的空余空间小于40%的时候,这个堆内存就会自动增长到-Xmx指定的最大堆分配内存。
JVM的最大堆分配内存由-Xmx指定,默认为物理内存的1/4,当空余内存大于70%的时候,该堆内存又会自动减少到-Xms指定的内存。
一般来说,服务器设置-Xms和-Xmx相等,以保证每次GC都要调整堆的大小。
1.2.JVM堆内存的内部分配
如图所以,在JVM堆中,又分为新生代,老生代。
对于新生代:用-Xmn来指定新生代的内存大小。当堆大小不变的情况下,新生代越大,老生代越小,默认新生代和老年代的比例为1:2,而且这个比例会严重影响系统性能,sun推荐为新生代占整个堆内存3/8。
同时可以看到,新生代中,又分为eden区域和两个Survivor区域。(由于回收机制采用复制算法,所以这样分,可看另一篇垃圾收集博文)默认比例为8:1:1,也就是说,可以用的内存为90%(另一篇垃圾收集博文说有为什么),当然,可以用-XX:SurvivorRatio设置eden和Survivor的比值,默认为8:1。
特别注意:最右侧的永久代在JDK8中已经不在存在,被元空间代替metaspace所代替。另外,在jdk7中,字符串内部池就已经从永久代中移除。
二.JVM非堆内存分配
-XX:Persize设置非堆内存初始值,默认为1/64。
-XX:MaxPersize设置非堆内存最大值,默认为1/64.
-Xss设置每个线程占用堆内存大小,现在默认为1M,以前为256K。设置线程越小,堆内存大小不变,可以创造的线程数越多(当然有一个限度)。但是这个值也需要经过严格的测试再设置。
三.利用上述所学配置更快的Eclipse
很多人感觉自己的elipse启动比较慢,其实并不是因为装的插件太多或者是导入的项目有点大,而是因为参数的设置不合理导致的。
1.可以在eclipse.ini里面添加-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-Xloggc:gc.log 看看启动的日志。
2.找到gc.log,如下图:
3.可以看出,GC了很多,这也是配置不好所导致。如下图:
4.抽取一条进行分析:
2014-09-24T07:58:05.988+0800: 0.248: [GC 0.248: [DefNew: 890K->64K(960K), 0.0051262 secs] 890K->425K(5056K), 0.0052003 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
对于890K->425K(5056K),表示括号里表示堆内存的总容量大小为5056K,890K表示GC前堆内存的使用容量,425K表示GC后堆内存的使用容量。这样我们不禁可以想到,
1.堆内存也太小了吧;2.5056K才使用了890K就GC了,怎么回事。先解决第一个问题,查看eclipse.ini文件,发现-Xms根据没有进行设置。如下图:
5.我们把堆内存初始大小设置为和-Xmx一样,避免频繁的调整堆内存大小。即在eclipse.ini文件中加入-Xms512m.
6.从日志中,又可以看出这样一条:
2014-09-24T08:21:08.336+0800: 3.581: [Full GC 3.581: [Tenured: 8708K->11412K(483968K), 0.1108629 secs] 27487K->11412K(520256K), [Perm : 16361K->16361K(16384K)], 0.1109529 secs] [Times: user=0.08 sys=0.02, real=0.11 secs]
对于 上面日志,可以看出是[Perm : 16361K->16361K(16384K)], 0.1109529 secs]永久代用完了,所以触发了这次GC,查看eclipse.ini,并没有设置-XX:PermSize
,所以导致永生代初始容量大小不足,导致不断扩容,所以结论即加上-XX:PermSize并且设置和
-XX:MaxPermSize一样,避免频繁的进行大小调整,即在eclipse.ini中加上-XX:PermSize=256m
7.调完之后[Full GC 倒是没了,可以[GC 还是有2.3十条,当然比之前已经好了很多了。我们再看看这些日志
2014-09-24T08:34:05.760+0800: 2.494: [GC 2.494: [DefNew: 32256K->4032K(36288K), 0.0268827 secs] 32256K->5082K(520256K), 0.0269956 secs] [Times: user=0.03 sys=0.00, real=0.02 secs]
我们发现, 从32256K->5082K(520256K)我们知道整个堆大小为512m,GC前才使用了30来m就GC了,怎么回事。再看[DefNew: 32256K->4032K(36288K),我们发现,新生代才30m左右,一般来说官方推荐新生代占整个堆大小的3/8.512m乘以3/8也就是192m,而现在只有30m左右。所以我们可以得出结论,没有设置新生代大小,所以导致新生代容量不足,所以我们在eclipse.ini文件中添加上-Xmn:192m.
8.最后调完,[GC 只剩4次了,并且启动相比之前也快速了很多。
总结,在eclipse.ini中加上:
-Xms512m
-Xmx512m
-Xmn192m
-XX:PermSize=256m
-XX:MaxPermSize=256m
-XX:ReservedCodeCacheSize=64m
-Dosgi.nls.warnings=ignore
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-Xloggc:gc.log
这也是我们为什么要学习这些-Xms,-Xmx等等的一些好处之一。