直接复制如下到eclipse.ini里面html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
-Xverify:none
-Xmn256m
-Xms1024m
-Xmx1024m
-Xss2m
-XX:PermSize=256m
-XX:MaxPermSize=256m
-XX:CompileThreshold=10000
-XX:MaxGCPauseMillis=10
-XX:MaxHeapFreeRatio=70
-XX:+UseFastAccessorMethods
-XX:+FailOverToOldVerifier
-XX:NewSize=280m
-XX:MaxNewSize=280m
-XX:CMSMarkStackSize=8M
-XX:CMSMarkStackSizeMax=32M
-XX:+DisableExplicitGC
-XX:+TraceClassLoading
-XX:+TraceClassUnloading
-XX:+CMSPermGenSweepingEnabled
-XX:CMSInitiatingOccupancyFraction=85
-XX:ReservedCodeCacheSize=64m
-verbose:gc
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Xloggc:gc.log
|
最近项目愈来愈大,有个项目2G左右。是一个多平台多项目的组合。eclipse启动有些受不了了。并且有些类几千行,改一下卡一下。java
一直用的myeclipse6.5,由于不占内存,启动快。后来想,过几年总要被新产品替代。索性直接用eclipse得了。可是发现最新的eclipse也是慢得很。linux
虽然本身之前也有经验调整一些启动参数,但效果很差。因而乎百度求最优解决方案。算法
首先把你eclipse不要的启动项,验证什么的都干掉。具体的请百度之。sql
而后就是eclipse启动参数!启动速度刚刚的啊。。。看加粗的部分。。。apache
若是加入后不能启动,试着去掉最下面的几行参数看看,要一行行的试,不要都去掉了。或者将前面的参数值设置小一点。各个参数以前可能会互相影响的。缓存
-vm
D:/java/jdk6/bin
-startup
plugins/org.eclipse.equinox.launcher_1.3.0.v20120522-1813.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.1.200.v20120522-1813
-product
org.eclipse.epp.package.jee.product
--launcher.defaultAction
openFile
--launcher.XXMaxPermSize
256M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m
--launcher.defaultAction
openFile
-vmargs
-server
-Dosgi.requiredJavaVersion=1.5
-Xms1024m
-Xmx1024m
-Xss2m
-XX:PermSize=128m
-XX:MaxPermSize=128m
-XX:+UseParallelGC
-Xverify:none
-XX:+DisableExplicitGC
-Xnoclassgc
#-XX:+UseParNewGC
#-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=85
-XX:ReservedCodeCacheSize=150m服务器
点击下面的查看:多线程
老外的方法并发
下面是后来看到的一篇文章,转贴在这里。http://www.cnblogs.com/chen77716/archive/2010/06/26/2130807.html
最近因项目存在内存泄漏,故进行大规模的JVM性能调优 , 现把经验作一记录。
1、JVM内存模型及垃圾收集算法
1.根据Java虚拟机规范,JVM将内存划分为:
其中New和Tenured属于堆内存,堆内存会从JVM启动参数(-Xmx:3G)指定的内存中分配,Perm不属于堆内存,有虚拟机直接分配,但能够经过-XX:PermSize -XX:MaxPermSize 等参数调整其大小。
New又分为几个部分:
2.垃圾回收算法
垃圾回收算法能够分为三类,都基于标记-清除(复制)算法:
JVM会根据机器的硬件配置对每一个内存代选择适合的回收算法,好比,若是机器多于1个核,会对年轻代选择并行算法,关于选择细节请参考JVM调优文档。
稍微解释下的是,并行算法是用多线程进行垃圾回收,回收期间会暂停程序的执行,而并发算法,也是多线程回收,但期间不中止应用执行。因此,并发算法适用于交互性高的一些程序。通过观察,并发算法会减小年轻代的大小,其实就是使用了一个大的年老代,这反过来跟并行算法相比吞吐量相对较低。
还有一个问题是,垃圾回收动做什么时候执行?
另外一个问题是,什么时候会抛出OutOfMemoryException,并非内存被耗空的时候才抛出
知足这两个条件将触发OutOfMemoryException,这将会留给系统一个微小的间隙以作一些Down以前的操做,好比手动打印Heap Dump。
2、内存泄漏及解决方法
1.系统崩溃前的一些现象:
以后系统会没法响应新的请求,逐渐到达OutOfMemoryError的临界值。
2.生成堆的dump文件
经过JMX的MBean生成当前的Heap信息,大小为一个3G(整个堆的大小)的hprof文件,若是没有启动JMX能够经过Java的jmap命令来生成该文件。
3.分析dump文件
下面要考虑的是如何打开这个3G的堆信息文件,显然通常的Window系统没有这么大的内存,必须借助高配置的Linux。固然咱们能够借助X-Window把Linux上的图形导入到Window。咱们考虑用下面几种工具打开该文件:
使用这些工具时为了确保加载速度,建议设置最大内存为6G。使用后发现,这些工具都没法直观地观察到内存泄漏,Visual VM虽能观察到对象大小,但看不到调用堆栈;HeapAnalyzer虽然能看到调用堆栈,却没法正确打开一个3G的文件。所以,咱们又选用了Eclipse专门的静态内存分析工具:Mat。
4.分析内存泄漏
经过Mat咱们能清楚地看到,哪些对象被怀疑为内存泄漏,哪些对象占的空间最大及对象的调用关系。针对本案,在ThreadLocal中有不少的JbpmContext实例,通过调查是JBPM的Context没有关闭所致。
另,经过Mat或JMX咱们还能够分析线程状态,能够观察到线程被阻塞在哪一个对象上,从而判断系统的瓶颈。
5.回归问题
Q:为何崩溃前垃圾回收的时间愈来愈长?
A:根据内存模型和垃圾回收算法,垃圾回收分两部分:内存标记、清除(复制),标记部分只要内存大小固定时间是不变的,变的是复制部分,由于每次垃圾回收都有一些回收不掉的内存,因此增长了复制量,致使时间延长。因此,垃圾回收的时间也能够做为判断内存泄漏的依据
Q:为何Full GC的次数愈来愈多?
A:所以内存的积累,逐渐耗尽了年老代的内存,致使新对象分配没有更多的空间,从而致使频繁的垃圾回收
Q:为何年老代占用的内存愈来愈大?
A:由于年轻代的内存没法被回收,愈来愈多地被Copy到年老代
3、性能调优
除了上述内存泄漏外,咱们还发现CPU长期不足3%,系统吞吐量不够,针对8core×16G、64bit的Linux服务器来讲,是严重的资源浪费。
在CPU负载不足的同时,偶尔会有用户反映请求的时间过长,咱们意识到必须对程序及JVM进行调优。从如下几个方面进行:
1.Java线程池(java.util.concurrent.ThreadPoolExecutor)
大多数JVM6上的应用采用的线程池都是JDK自带的线程池,之因此把成熟的Java线程池进行罗嗦说明,是由于该线程池的行为与咱们想象的有点出入。Java线程池有几个重要的配置参数:
Java线程池须要传入一个Queue参数(workQueue)用来存放执行的任务,而对Queue的不一样选择,线程池有彻底不一样的行为:
SynchronousQueue:
一个无容量的等待队列,一个线程的insert操做必须等待另外一线程的remove操做,采用这个Queue线程池将会为每一个任务分配一个新线程
LinkedBlockingQueue :
无界队列,采用该Queue,线程池将忽略
maximumPoolSize参数,仅用corePoolSize的线程处理全部的任务,未处理的任务便在LinkedBlockingQueue中排队
ArrayBlockingQueue: 有界队列,在有界队列和
maximumPoolSize的做用下,程序将很难被调优:更大的Queue和小的maximumPoolSize将致使CPU的低负载;小的Queue和大的池,Queue就没起动应有的做用。其实咱们的要求很简单,但愿线程池能跟链接池同样,能设置最小线程数、最大线程数,当最小数<任务<最大数时,应该分配新的线程处理;当任务>最大数时,应该等待有空闲线程再处理该任务。
但线程池的设计思路是,任务应该放到Queue中,当Queue放不下时再考虑用新线程处理,若是Queue满且没法派生新线程,就拒绝该任务。设计致使“先放等执行”、“放不下再执行”、“拒毫不等待”。因此,根据不一样的Queue参数,要提升吞吐量不能一味地增大maximumPoolSize。
固然,要达到咱们的目标,必须对线程池进行必定的封装,幸运的是ThreadPoolExecutor中留了足够的自定义接口以帮助咱们达到目标。咱们封装的方式是:
2.链接池(org.apache.commons.dbcp.BasicDataSource)
在使用org.apache.commons.dbcp.BasicDataSource的时候,由于以前采用了默认配置,因此当访问量大时,经过JMX观察到不少Tomcat线程都阻塞在BasicDataSource使用的Apache ObjectPool的锁上,直接缘由当时是由于BasicDataSource链接池的最大链接数设置的过小,默认的BasicDataSource配置,仅使用8个最大链接。
我还观察到一个问题,当较长的时间不访问系统,好比2天,DB上的MySQL会断掉因此的链接,致使链接池中缓存的链接不能用。为了解决这些问题,咱们充分研究了BasicDataSource,发现了一些优化的点:
3.JVM参数
在JVM启动参数中,能够设置跟内存、垃圾回收相关的一些参数设置,默认状况不作任何设置JVM会工做的很好,但对一些配置很好的Server和具体的应用必须仔细调优才能得到最佳性能。经过设置咱们但愿达到一些目标:
前两个目前是相悖的,要想GC时间小必需要一个更小的堆,要保证GC次数足够少,必须保证一个更大的堆,咱们只能取其平衡。
(1)针对JVM堆的设置通常,能够经过-Xms -Xmx限定其最小、最大值,为了防止垃圾收集器在最小、最大之间收缩堆而产生额外的时间,咱们一般把最大、最小设置为相同的值
(2)年轻代和年老代将根据默认的比例(1:2)分配堆内存,能够经过调整两者之间的比率NewRadio来调整两者之间的大小,也能够针对回收代,好比年轻代,经过 -XX:newSize -XX:MaxNewSize来设置其绝对大小。一样,为了防止年轻代的堆收缩,咱们一般会把-XX:newSize -XX:MaxNewSize设置为一样大小
(3)年轻代和年老代设置多大才算合理?这个我问题毫无疑问是没有答案的,不然也就不会有调优。咱们观察一下两者大小变化有哪些影响
(4)在配置较好的机器上(好比多核、大内存),能够为年老代选择并行收集算法: -XX:+UseParallelOldGC ,默认为Serial收集
(5)线程堆栈的设置:每一个线程默认会开启1M的堆栈,用于存放栈帧、调用参数、局部变量等,对大多数应用而言这个默认值太了,通常256K就足用。理论上,在内存不变的状况下,减小每一个线程的堆栈,能够产生更多的线程,但这实际上还受限于操做系统。
(4)能够经过下面的参数打Heap Dump信息
经过下面参数能够控制OutOfMemoryError时打印堆的信息
请看一下一个时间的Java参数配置:(服务器:Linux 64Bit,8Core×16G)
JAVA_OPTS="$JAVA_OPTS -server -Xms3G -Xmx3G -Xss256k -XX:PermSize=128m -XX:MaxPermSize=128m -XX:+UseParallelOldGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/aaa/dump -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/usr/aaa/dump/heap_trace.txt -XX:NewSize=1G -XX:MaxNewSize=1G"
通过观察该配置很是稳定,每次普通GC的时间在10ms左右,Full GC基本不发生,或隔很长很长的时间才发生一次
经过分析dump文件能够发现,每一个1小时都会发生一次Full GC,通过多方求证,只要在JVM中开启了JMX服务,JMX将会1小时执行一次Full GC以清除引用,关于这点请参考附件文档。
4.程序算法调优:本次不做为重点
参考资料:
http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html