1. java.lang.OutOfMemoryError: PermGen space 持久代内存溢出
持久代主要存放Class字节码信息,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理。
解决方法(具体数值按需设置):
初始持久代内存大小:-XX:PermSize=256m
最大持久代内存大小:-XX:MaxPermSize=1024m
tomcat的bin目录下catalina.sh设置方法:
在echo "Using CATALINA_BASE: $CATALINA_BASE"
上面添加JAVA_OPTS="-server -XX:PermSize=256M -XX:MaxPermSize=1024m
编辑器IDEA设置方法:
2. java.lang.OutOfMemoryError: Java heap space 堆内存溢出
解决方法:
JVM初始化堆内存大小:-Xms256M(默认物理内存的1/64(<1GB))
JVM最大的堆内存大小:-Xmx2048M(默认物理内存的1/4(<1GB))
Server端JVM建议-Xms设置与-Xmx相同,可以避免每次垃圾回收完成后JVM重新分配内存。
设置新生代大小:-Xmn,整个堆大小=新生代大小 + 年老代大小。
增大新生代后,将会减小年老代大小,此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
代码获取内存信息:
Runtime.getRuntime().maxMemory()//获取最大内存
Runtime.getRuntime().freeMemory()//获取空闲内存
Runtime.getRuntime().totalMemory()//获取可用总内存
Java会尽可能将可用总内存的值维持在最小堆内存。
3. java.lang.StackOverflowError:栈溢出
通常是由于递归调用造成的,所以写递归的时候,一定不要少了递归出口。快速排序、树节点组装等都少不了递归。
栈主要存放局部变量,先进后出原则
设置每个线程的栈大小:-Xss128K(实际值需要经过严格的测试)。
JDK5.0以后每个线程栈大小为1M,以前每个线程栈大小为256K。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数是有限制的,不能无限生成,经验值在3000~5000左右。
在程序中查询配置参数:
List<String> arguments = ManagementFactory.getRuntimeMXBean().getInputArguments();
System.out.println(StringUtils.join(arguments,","));
打印输出:
-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:56570,suspend=y,server=n,-Xms256M,-Xmx1024M,-XX:PermSize=256m,-XX:MaxPermSize=1024m,-Dmaven.home=D:\Tools\apache-maven-2.2.1,-Dclassworlds.conf=D:\Tools\apache-maven-2.2.1\bin\m2.conf,-Dfile.encoding=UTF-8