nbfcome 2011-04-12
Java堆内存大小设置:-Xms最小值 -Xmx最大值 内存不足时:
java.lang.OutofMemoryError:Java heap space;
虚拟机栈和本地方法栈设置: -Xss 内存不足时:
java.lang.StackOverflowError
方法区(永久代)设置:-XX:PermSize和-XX:MaxPermSize 内存不足时:
java.lang.OutofMemorError:PermGen space
本机直接内存设置:-XX:MaxDirectMemorySize 内存不足时:
java.lang.OutofMemoryError at sun.misc.Unsafe.allocateMemory(Native Method)
下面来说一下JVM内存组成,下面是一个示意图,其它的百分比,不准确,只是用来表示大意
由上图可以看出Java堆、方法区和本机直接内存占了Java可用计算机内在的绝大部分。
其中,
Java堆中主要用来存放Java对象的实例、数组等,线程共享;
方法区主要用来存放Java类信息和常量、静态变量等,线程共享;
本地方法栈和虚拟机栈类似,用来存放局部变量表、操作栈等,线程独享;区别在于本地方法栈为虚拟机使用到Native方法服务,而虚拟机栈为虚拟机执行Java方法服务;
程序计算器可以看做是当前线程所执行的字节码的行号指示器,线程独享;大小可以忽略不计。
本机直接内存,它并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用;比如New Input/Output类,使用基于Channel和Buffer的I/O方式,它可以使用Native函数库直接分配堆外内存(本机直接内存),然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。本机直接内存的大小默认为-Xmx设置的Java堆内存。
Java堆内存又分为年轻代(新生代)和年老代。最建Java对象,优先放到新生代(大对象,可能直接放到年老代,可以通过参数-XX:PretenureSizeThreshold设置临界对象大小),新生代中的对象,每经过一次垃圾回收(Minor GC)就长一岁,达到一定年龄(默认为15岁)的Java对象,或符合其它规则的对象,会从年轻代转移到年老代。
年轻代又可以分为1个Eden和2个Survivor。默认Eden:Survivor(1个)为8:1,可以通过参数-XX:SurvivorRatio来设置。新建Java对象先放到Eden区中,通过一次Minor GC后,仍然存活的Java对象(包括Eden和其中一个Survivor区),年龄长1,然后转移到另外一个Survivor区中。 这里这么设置是为了Java对象的垃圾收集。此处使用的是Java垃圾收集算法的“复制算法”,其它算法的还有“标记-清除”和“标记-整理”。关于Java垃圾回收算法和Java垃圾收集器请查看其它相关资料。
SGA概述Oracle的SGA包括以下几个部分,可以通过show sga命令或者是通过查看v$sga视图来查看SGA的大概组成:。解释一下这里“虚拟内存”的含义,确切的应该这样说:实际内存和虚拟内存。