java启动时如何怎样才能学好java立马分配一个固定大小的内存

一步步优化JVM四:决定Java堆的大小以及内存占用
到目前为止,还没有做明确的优化工作。只是做了初始化选择工作,比如说:JVM部署模型、JVM运行环境、收集哪些垃圾回收器的信息以及需要遵守垃圾回收原则。这一步将介绍如何评估应用需要的内存大小以及Java堆大小。首先需要判断出应用存活的数据的大小,存活数据的大小是决定配置应用需要的Java堆大小的重要条件,也能够决定是否需要重新审视一下应用的内存需求或者修改应用程序以满足内存需求。
注意:存活数据是指,应用处于稳定运行状态下,在Java堆里面长期存活的对象。换一句话说,就是应用在稳定运行的状态下,Full GC之后,Java堆的所占的空间。
有多少物理内存可以供JVM使用?是部署多个JVM或者单个JVM?对做出的决定有重要影响。下面列出了一些要点可以帮助决定有多少物理内存可以供使用。
1、一个机器上面只是部署一个JVM,且就一个应用使用?如果是这种情况,那么机器的所有物理内存可以供JVM使用。
2、一个机器上部署了多个JVM?或者一个机器上部署了多个应用?如果是这两个中的任何一种情况,你就必须要决定每一个JVM或者应用需要分配多少内存了。
无论是前面的哪种情况,都需要给操作系统留出一些内存。
HotSpot VM的堆结构
在做内存占用测量之前,我们必须要先理解HotSpot VM Java堆的结构,理解这个对决定应用需要的Java堆大小以及优化垃圾收器性能有很好的帮助。
HotSpot VM有3个主要的空间:young代、old代以及permanent代,如上图所示。
当Java应用分配Java对象时,这些对象被分配到young代。在经历过几次minor GC之后,如果对象还是存活的,就会被转移到old代空间。permanent代空间存储了VM和Java类的元数据比如内置的字符串和类的静态变量。
-Xmx和-Xms这个两个命令行选项分别指定yound代加上old代空间的总和的初始最大值和最小值,也就是Java堆的大小。当-Xms的值小于-Xmx的值的时候,Java堆的大小可以在最大值和最小值之前浮动。当Java应用强调吞吐量和延迟的时候,倾向于把-Xms和-Xmx设置成相同的值,由于调整young代或者old代的大小都需要进行Full GC,Full GC降低吞吐量以及加强延迟。
young代的空间可以通过下面的任意一个命令行选项来设置:
1、-XX:NewSize=&n&[g|m|k]
young代的初始值和最小值。&n&是大小,[g|m|k]表示单位是G字节,M字节或者千字节。young代的大小不会小于这个值。当设定-XX:NewSize=&n&[g|m|k]的时候,-XX:MaxNewSize=&n&[g|m|k]需要被指定。
2、-XX:MaxNewSize=&n&[g|m|k]
young区空间的最大值。同上面反过来,当指定-XX:MaxNewSize=&n&[g|m|k]的需要指定-XX:NewSize=&n&[g|m|k]。
3、-Xmn&n&[g|m|k]
直接指定young代的初始值、最小值以及最大值。也就是说,young区的大小被固定成这个值了。这个值用来锁定young代的大小很方便。
有一点需要注意的是,如果-Xms和-Xmx没有被设定成相同的值,而且-Xmn被使用了,当调整Java堆的大小的时候,不会调整young代的空间大小,young代的空间大小会保持恒定。因此,-Xmn应该在-Xms和-Xmx设定成相同的时候才指定。
old代的空间大小可以基于young代的大小进行计算,old代的初始值的大小是-Xms的值减去-XX:NewSize,最大值是-Xmx减去-XX:MaxNewSize,如果-Xmx和-Xms设置成了相同的值,而且使用-Xmn选项或者-XX:NewSize和-XX:MaxNewSize设置成了相同的值,那么old代的大小就是-Xmx减去-Xmn。
permanent代的大小通过下面命令行参数指定
1、-XX:PermSize=&n&[g|m|k]
表示permanent代的初始值和最小值,n表示数值,g|m|k表示单位、permanent的空间一定不会比这个空间小。
2、-XX:MaxPermSize=&n&[g|m|k]
permanent代的最大值,permanent代的大小不会超过这个值。
Java应用应该指定这两个值成为同一个值,由于这个值的调整会导致Full GC。
如果上面提到的Java堆大小、young代、permanent代的大小都没有指定,那么JVM会根据应用的情况自行计算。
在young代、old代以及permanent代中任何一个空间里面无法分配对象的时候就会触发垃圾回收,理解这点,对后面的优化非常重要。当young代没有足够空间分配Java对象的时候,触发minor GC。minor GC相对于Full
GC来说会更短暂。
一个对象在经历过一定次数的Minor GC之后,如果还存活,那么会被转移到old代(对象有一个“任期阀值”的概念,优化延迟的时候再介绍)。当old代没有足够空间放置对象的时候,HotSpot VM触发full GC。实际上在进行Minor GC的时候发现没有old代足够的空间来进行对象的转移,就会触发FullGC,相对于在MinorGC的过程中发现对象的移动失败了然后触发FullGC,这样的策略会有更小的花费。当permanent代的空间不够用的时候的,也会触发FullGC。
如果FullGC是由于old代满了而触发的,old代和permanent代的空间都会被垃圾回收,即使permanent代的空间还没有满。同理,如果FullGC是由于permanent代满了而触发的,old代和permanent代的空间都会被垃圾回收,即使old代的空间还没有满。另外,young代同样会被垃圾回收,除非-XX:+ScavengeBeforeFullGC选项被指定了,-XX:+ScavengeBeforeFullGC关闭FullGC的时候young代的垃圾回收。
堆大小优化的起点
为了进行Java堆大小的优化,一个合适的起点很重要。这节描述的方案是需要先使用比应用需要量更大的Java堆作为开始。这一步的目的是收集一些初始化信息以及为了进一步优化Java堆大小需要的数据。
就像在“选择JVM runtime”小节里面提到过的,由吞吐量垃圾回收器(throughput garbage collector)开始。记住,使用吞吐量垃圾回收器通过设置-XX:+UserParallelOldGC命令行选项,如果你使用的HotSpot VM不支持的这个选项,那么就使用-XX:+UserParallelGC。
如果你能够准确的预估到应用需要消耗的Java堆空间,可以通过设定-Xmx和-Xms来作为这个步骤的起点。如果你不知道该设定什么值,就让JVM来选择吧,反正后面,都会根据实际情况进行优化调整。
关于如何监控GC日志前面的“GC优化基础”已经描述过了。GC日志会展示在使用中的java堆的大小。初始化和最大的堆大小可以通过-XX:+PrintCommandLineFlags来查看。-XX:+PrintCommandLineFlags打印出在HotSpot VM初始化的时候选择的初始值和最大值比如-XX:InitialHeapSize=&n&
-XX:MaxHeapSize=&m&,这里n表示初始化的java堆大小值,m表示java堆的最大值。
不管你是指定java堆的大小还是使用默认的大小,必须让应用进入稳定运行的状态,你必须要有能力和手段让应用处于和线上稳定运行的状态相同的状态。
如果在企图让应用进入稳定状态的时候,你在垃圾回收日志里面观察到OutOfMemoryError,注意是old代溢出还是permanent代溢出。下面一个old代溢出的例子:
T18:51:03.895-0600: [Full GC[PSYoungGen: 279700K-&8400K)]
[ParOldGen: 685165K-&5170K)]
964865K-&43570K)
[PSPermGen: 32390K-&3K)],0.2499342 secs]
[Times: user=0.08 sys=0.00, real=0.05 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
上面重要的部分加粗标示了,由于使用的是吞吐量垃圾回收器,old代的统计信息标示为ParOldGen。这行表示了old代的在FullGC的时候占用的空间。从这个结果来看,可以得出的结论是old代的空间太小了,由于FullGC前后old代的被占用的空间和分配的空间基本相等了,因此,JVM报了OutOfMemoryError。相比较,通过PSPermGen这行可以看出permanent代的空间占用是32390K,和他的容量(65536K)比还是有一定的距离。
下面的例子展示了由于permanent太少了而导致的OutOfMemoryError发生的例子
T18:26:37.755-0600: [Full GC
[PSYoungGen: 0K-&0K(141632K)]
[ParOldGen: 132538K-&0208K)]
32538K-&3K)
[PSPermGen: 65536K-&6K)],
0.2430136 secs]
[Times: user=0.37 sys=0.00, real=0.24 secs]
java.lang.OutOfMemoryError: PermGen space
同上面一样,把关键行标示出来了,通过PSPermGen这行可以看出在FullGC前后,他的空间占用量都和他的容量相同,可以得出的结论是permanent代的空间条小了,这样就导致了OutOfMemoryError。在这个例子里面,old的占用空间(132538K)远比他的容量(350208K)小。
如果在垃圾回收日志中观察到OutOfMemoryError,尝试把Java堆的大小扩大到物理内存的80%~90%。尤其需要注意的是堆空间导致的OutOfMemoryError以及一定要增加空间。比如说,增加-Xms和-Xmx的值来解决old代的OutOfMemoryError,增加-XX:PermSize和-XX:MaxPermSize来解决permanent代引起的OutOfMemoryError。记住一点Java堆能够使用的容量受限于硬件以及是否使用64位的JVM。在扩大了Java堆的大小之后,再检查垃圾回收日志,直到没有OutOfMemoryError为止。
如果应用运行在稳定状态下没有OutOfMemoryError就可以进入下一步了,计算活动对象的大小。
计算活动对象的大小
就像前面提到的,活动对象的大小是应用处于稳定运行状态时,长时间存活数据占用的Java堆的空间大小。换句话说,就是应用稳定运行是,在FullGC之后,old代和permanent代的空间大小。
活动对象的大小可以通过垃圾回收日志查看,它提供了一些优化信息,如下:
1、应用处于稳定运行状态下,old代的Java堆空间占用数量。
2、应用处于稳定运行状态下,permanent代的Java堆空间占用数量。
为了保证能够准确的评估应用的活动对象大小,最好的做法是多看几次FullGC之后Java堆空间的大小,保证FullGC是发生在应用处于稳定运行的状态。
如果应用没有发生FullGC或者发生FullGC的次数很少,在性能测试环境,可以通过Java监控工具来触发FullGC,比如使用VisualVM和JConsole,这些工具在最新的JDK的bin目录下可以找到,VisualVM集成了JConsole,VisualVM或者JConsole上面有一个触发GC的按钮。
另外,jmap命令可以选择来强制HotSpot VM进行FullGC。jmap 需要-histo:live命令选项以及JVM进程id。JVM的进程id可以通过jps命令获取。比如JVM的进程id是348,jmap命令用来触发FullGC可以想如下这样写:
$ jmap -histo:live 348
jmap不仅仅触发FullGC,而且产生堆的关于对象分配的概要信息。不过就目前这步的目的而言,可以忽略产生的堆概要信息。
初始化堆大小配置
本节描述了怎样利用活动对象的大小来决定初始化的Java堆的大小。下面的图,给出了应用存活的对象的大小。比较明智的做法是多收集几次FullGC信息,有更多的信息,能够做出更加好的决定。
通过活动对象大小的信息,可以做出关于Java堆的大小有根据的决定,以及可以估计出最坏情况下会导致的延迟。
比较常规是,Java堆大小的初始化值和最大值(通过-Xms和-Xmx选项来指定)应该是old代活动对象的大小的3到4倍。
在上图中显示的FullGC信息中,在FullGC之后old代的大小是295111K,差不多是295M,即活动的对象的大小是295M。因此,推荐的Java堆的初始化和最大值应该是885M到1180M,即可以设置为-Xms885m -Xmx1180m。在这个例子中,Java堆的大小是1048570K差不多1048M,在推荐值范围内。
另外一个常规是,permanent的初始值和最大值(-XX:PermSize和-XX:MaxPermSize)应该permanent代活动对象大小的1.2到1.5倍。在上图中看到在FullGC之后permanent代占用空间是32390K,差不多32M。因此,permanent代的推荐大小是38M到48M,即可以设置为-XX:PermSize=48m -XX:MaxPermSize=48m(1.5倍)。这个例子里面,permanent代的空间大小是65536K即64M,大出了17M,不过在1G内存的系统的中,这个数值完全可以忍受。
另外一个常规是,young代空间应该是old代活动对象大小的1到1.5倍。那么在这里例子中,young代的大小可以设置为295M到442M。本例里面,young代的空间大小的358400K,差不多358M,在推荐值中间。
如果推荐的Java堆的初始值和最大值是活动对象大小3到4倍,而young代的推荐只是1到1.5倍,那么old代空间大小应该是2到3倍。
通过以上规则,我们可以使用的Java命令可以是这样的:
java -Xms1180m -Xmx1180m -Xmn295m -XX:PermSize=48m -XX:MaxPermSize=48m
另外一些考虑
本节将提及到在进行应用内存占用评估的时候,另外一些需要记住的点。首先,必须要知道,前面只是评估的Java堆的大小,而不是Java应用占用的所有的内存,如果要查看Java应用占用的所有内存在linux下可以通过top命令查看或者在window下面通过任务管理器来查看,尽管Java堆的大小可能对Java应用占用内存做出了最大的贡献。 比如说,为了存储线程堆栈,应用需要额外的内存,越多的线程,越多内存被线程栈消耗,越深的方法间调用,线程栈越多。另外,本地库需要分配额外的内存,I/O缓存也需要额外的内存。应用的内存消耗需要评估到应用任何一个会消耗内存的地方。
记住,这一步操作不一定能够满足应用内存消耗的需求,如果不能满足,就回过头来看需求是否合理或者修改应用程序。比较可行的一种办法是修改应用程序减小对象的分配,从而减少内存的消耗。
Java堆的大小计算仅仅只是开始,根据需求,在后面的优化步骤中可能会修改。
没有更多推荐了,如何调整java虚拟机内存大小_百度知道
该问题可能描述不清,建议你
如何调整java虚拟机内存大小
我有更好的答案
在一些规模稍大的应用中,Java虚拟机(JVM)的内存设置尤为重要,想在项目中取得好的效率,GC(垃圾回收)的设置是第一步。PermGen space:全称是Permanent Generation space.就是说是永久保存的区域,用于存放Class和Meta信息,Class在被Load的时候被放入该区域Heap space:存放Instance。GC(Garbage Collection)应该不会对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误Java Heap分为3个区1.Young2.Old3.PermanentYoung保存刚实例化的对象。当该区被填满时,GC会将对象移到Old区。Permanent区则负责保存反射对象,本文不讨论该区。JVM的Heap分配可以使用-X参数设定,-Xms 初始Heap大小-Xmx java heap最大值 -Xmn young generation的heap大小JVM有2个GC线程第一个线程负责回收Heap的Young区第二个线程在Heap不足时,遍历Heap,将Young 区升级为Older区Older区的大小等于-Xmx减去-Xmn,不能将-Xms的值设的过大,因为第二个线程被迫运行会降低JVM的性能。为什么一些程序频繁发生GC?有如下原因:1.程序内调用了System.gc()或Runtime.gc()。2.一些中间件软件调用自己的GC方法,此时需要设置参数禁止这些GC。3.Java的Heap太小,一般默认的Heap值都很小。4.频繁实例化对象,Release对象 此时尽量保存并重用对象,例如使用StringBuffer()和String()。如果你发现每次GC后,Heap的剩余空间会是总空间的50%,这表示你的Heap处于健康状态,许多Server端的Java程序每次GC后最好能有65%的剩余空间经验之谈:1.Server端JVM最好将-Xms和-Xmx设为相同值。为了优化GC,最好让-Xmn值约等于-Xmx的1/3。2.一个GUI程序最好是每10到20秒间运行一次GC,每次在半秒之内完成。注意:1.增加Heap的大小虽然会降低GC的频率,但也增加了每次GC的时间。并且GC运行时,所有的用户线程将暂停,也就是GC期间,Java应用程序不做任何工作。2.Heap大小并不决定进程的内存使用量。进程的内存使用量要大于-Xmx定义的值,因为Java为其他任务分配内存,例如每个线程的Stack等。Stack的设定每个线程都有他自己的Stack。-Xss 每个线程的Stack大小Stack的大小限制着线程的数量。如果Stack过大就好导致内存溢漏。-Xss参数决定Stack大小,例如-Xss1024K。如果Stack太小,也会导致Stack溢漏。硬件环境硬件环境也影响GC的效率,例如机器的种类,内存,swap空间,和CPU的数量。如果你的程序需要频繁创建很多transient对象,会导致JVM频繁GC。这种情况你可以增加机器的内存,来减少Swap空间的使用。4种GC1、第一种为单线程GC,也是默认的GC,该GC适用于单CPU机器。2、第二种为Throughput GC,是多线程的GC,适用于多CPU,使用大量线程的程序。第二种GC与第一种GC相似,不同在于GC在收集Young区是多线程的,但在Old区和第一种一样,仍然采用单线程。-XX:+UseParallelGC参数启动该GC。3、第三种为Concurrent Low Pause GC,类似于第一种,适用于多CPU,并要求缩短因GC造成程序停滞的时间。这种GC可以在Old区的回收同时,运行应用程序。-XX:+UseConcMarkSweepGC参数启动该GC。4、第四种为Incremental Low Pause GC,适用于要求缩短因GC造成程序停滞的时间。这种GC可以在Young区回收的同时,回收一部分Old区对象。-Xincgc参数启动该GC。单文件的JVM内存进行设置默认的java虚拟机的大小比较小,在对大数据进行处理时java就会报错:java.lang.OutOfMemoryError。设置jvm内存的方法,对于单独的.class,可以用下面的方法对Test运行时的jvm内存进行设置。java -Xms64m -Xmx256m Test-Xms是设置内存初始化的大小-Xmx是设置最大能够使用内存的大小(最好不要超过物理内存大小)tomcat启动jvm内存设置Linux:在/usr/local/apache-tomcat-5.5.23/bin目录下的catalina.sh添加:JAVA_OPTS='-Xms512m -Xmx1024m'要加“m”说明是MB,否则就是KB了,在启动tomcat时会报内存不足。-Xms:初始值-Xmx:最大值-Xmn:最小值Windows在catalina.bat最前面加入set JAVA_OPTS=-Xms128m -Xmx350m 如果用startup.bat启动tomcat,OK设置生效.够成功的分配200M内存.但是如果不是执行startup.bat启动tomcat而是利用windows的系统服务启动tomcat服务,上面的设置就不生效了,就是说set JAVA_OPTS=-Xms128m -Xmx350m 没起作用.上面分配200M内存就OOM了..windows服务执行的是bin\tomcat.exe.他读取注册表中的值,而不是catalina.bat的设置.解决办法:修改注册表HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Tomcat Service Manager\Tomcat5\Parameters\JavaOptions原值为-Dcatalina.home=&C:\ApacheGroup\Tomcat 5.0&-Djava.endorsed.dirs=&C:\ApacheGroup\Tomcat 5.0\common\endorsed&-Xrs加入 -Xms300m -Xmx350m重起tomcat服务,设置生效weblogic启动jvm内存设置在weblogic中,可以在startweblogic.cmd中对每个domain虚拟内存的大小进行设置,默认的设置是在commEnv.cmd里面。JBoss默认可以使用的内存为64MB $JBOSSDIR$/bin/run.config JAVA_OPTS = &-server -Xms128 -Xmx512&Eclipse在所在目录下,键入 eclipse.exe -vmargs -Xms256m -Xmx512m 256m表示JVM堆内存最小值 512m表示JVM堆内存最大Websphere进入控制台去设置:应用程序服务器 & server1 & 进程定义 & Java 虚拟机
采纳率:64%
来自团队:
1. 设置JVM内存的参数有四个:-Xmx
Java Heap最大值,默认值为物理内存的1/4,最佳设值应该视物理内存大小及计算机内其他内存开销而定;-Xms
Java Heap初始值,Server端JVM最好将-Xms和-Xmx设为相同值,开发测试机JVM可以保留默认值;-Xmn
Java Heap Young区大小,不熟悉最好保留默认值;-Xss
每个线程的Stack大小,不熟悉最好保留默认值;2. 如何设置JVM内存分配: 当在命令提示符下启动并使用JVM时(只对当前运行的类Test生效):java -Xmx128m -Xms64m -Xmn32m -Xss16m Test
本回答被提问者和网友采纳
为您推荐:
其他类似问题
java虚拟机的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。http://blog.itpub.net//viewspace-696834/
http://lqding.blog.51cto.com/3659
& & & &&一、概述:&&& & &&& & & & &&
的内存可以按照共享和私有的角度分为系统全局区和进程全局区,也就是 SGA和 PGA(process global area or private
global area)。对于 SGA 区域内的内存来说,是共享的全局的,在 UNIX 上,必须为 oracle
设置共享内存段(可以是一个或者多个),因为 oracle 在UNIX 上是多进程;而在 WINDOWS 上 oracle
是单进程(多个线程),所以不用设置共享内存段。PGA
是属于进程(线程)私有的区域。在 oracle 使用共享服务器模式下(MTS),PGA中的一部分,也就是 UGA 会被放入共享内存
large_pool_size 中。
& & & &发张图oracle内存架构组成,按照图上面的显示可以一目了然关键的参数和参数名称:
对于 SGA 部分,我们通过 sqlplus 中查询可以看到:
SQL& select * from v$&
NAME & & & & & & & &VALUE&
---------- & & & & & & --------------------
Fixed Size & & & & & & & & & 454032&
Variable Size & & & & & & &
Database Buffers & & & & & & &
Redo Buffers & & & & & & & &667648&
Fixed Size: &&& & &&
oracle 的不同平台和不同版本下可能不一样,但对于确定环境是一个固定的值,里面存储了 SGA 各部分组件的信息,可以看作引导建立 SGA 的区域。
Variable Size :&&& & &&
包含了 shared_pool_size、java_pool_size、large_pool_size 等内存设置
Database Buffers :& &&& &
指数 据缓 冲区: & & & &&
在 8i 中包 含 db_block_buffer*db_block_size、buffer_pool_keep、buffer_pool_recycle 三 部 分内 存 。&& & & &&
在 9i 中 包 含 db_cache_size 、db_keep_cache_size、db_recycle_cache_size、db_nk_cache_size。
Redo Buffers :& &&& &&
指日志缓冲区,log_buffer。
在这里要额外说明一点的是,对于 v$parameter、v$sgastat、v$sga 查询值可能不一样。v$parameter 里面的值,是指用户在初
始化参数文件里面设置的值,v$sgastat 是 oracle 实际分配的日志缓冲区大小(因为缓冲区的分配值实际上是离散的,也不是以 block 为最小单位进行分配的),
v$sga 里面查询的值,是在 oracle 分配了日志缓冲区后,为了保护日志缓冲区,设置了一些保护页,通常我们会发现保护页大小大约是 11k(不同环境可能不一样)。& & & &
二、SGA内参数及设置:&&& & & & & &&
2.1 &Log_buffer&
对于日志缓冲区的大小设置,通常我觉得没有过多的建议,因为参考 LGWR 写的触发条件之后,我们会发现通常超过 3M 意义不是很大。作为一个正式系统,可能考虑先设置这部分为 log_buffer=3—5M &大小,然后针对具体情况再调整。
log_buffer是Redo log的buffer。
因此在这里必须要了解Redo Log的触发事件(LGWR)
1、当redo log buffer的容量达到1/3
2、设定的写redo log时间间隔到达,一般为3秒钟。
3、redo log buffer中重做日志容量到达1M
4、在DBWn将缓冲区中的数据写入到数据文件之前
5、每一次commit--提交事务。
上面的结论可以换句话说
1、log_buffer中的内容满1/3,缓存刷新一次。
2、最长间隔3秒钟,缓存刷新一次
3、log_buffer中的数据到达1M,缓存刷新一次。
4、每次提交一个“事务”,缓存刷新一次
2.2 Large_pool_size&
对于大缓冲池的设置,假如不使用 MTS(共享服务器),建议在 20—30M &足够了。这部分主要用来保存并行查询时候的一些信息,还有就是 RMAN 在备份的时候可能会使用到。如果设置了MTS,则由于 UGA 部分要移入这里,则需要具体根据 server process 数量和相关会话内存参数的设置来综合考虑这部分大小的设置。
2.3 &Java_pool_size&
假如数据库没有使用 JAVA,我们通常认为保留 10—20M 大小足够。事实上可以更少,甚至最少只需要 32k,但具体跟安装数据库的时候的组件相关(比如 http server)。
2.4 &Shared_pool_size
Shared_pool_size的开销通常应该维持在300M 以内。除非系统使用了大量的存储过程、函数、包,比如 oracle erp 这样的应用,可能会达到 500M 甚至更高。于是我们假定一个 1G 内存的系统,可能考虑设置该参数为 100M,2G 的系统考虑设置为 150M,8G 的系统可以考虑设置为 200—300M
2.5SGA_MAX_SIZE
SGA区包括了各种缓冲区和内存池,而大部分都可以通过特定的参数来指定他们的大小。但是,作为一个昂贵的资源,一个系统的物理内存大小是有限。尽管对于CPU的内存寻址来说,是无需关系实际的物理内存大小的(关于这一点,后面会做详细的介绍),但是过多的使用虚拟内存导致page in/out,会大大影响系统的性能,甚至可能会导致系统crash。所以需要有一个参数来控制SGA使用虚拟内存的最大大小,这个参数就是SGA_MAX_SIZE。当实例启动后,各个内存区只分配实例所需要的最小大小,在随后的运行过程中,再根据需要扩展他们的大小,而他们的总和大小受到了SGA_MAX_SIZE的限制。
对于OLTP系统,参考:
SGA_MAX_SIZE值
2.6&PRE_PAGE_SGA
oracle实例启动时,会只载入各个内存区最小的大小。而其他SGA内存只作为虚拟内存分配,
只有当进程touch到相应的页时,才会置换到物理内存中。但我们也许希望实例一启动后,所有SGA
都分配到物理内存。这时就可以通过设置PRE_PAGE_SGA参数来达到目的了。这个参数的默认值
为FALSE,即不将全部SGA置入物理内存中。当设置为TRUE时,实例启动会将全部SGA置入物理
内存中。它可以使实例启动达到它的最大性能状态,但是,启动时间也会更长(因为为了使所有SGA
都置入物理内存中,oracle进程需要touch所有的SGA页)。
2.7 LOCK_SGA
为了保证SGA都被锁定在物理内存中,而不必页入/页出,可以通过参数LOCK_SGA来控制。
这个参数默认值为FALSE,当指定为TRUE时,可以将全部SGA都锁定在物理内存中。当然,
有些系统不支持内存锁定,这个参数也就无效了。
2.8 SGA_TARGET
这里要介绍的时Oracle10g中引入的一个非常重要的参数。在10g之前,SGA的各个内存区
的大小都需要通过各自的参数指定,并且都无法超过参数指定大小的值,尽管他们之和可能并
没有达到SGA的最大限制。此外,一旦分配后,各个区的内存只能给本区使用,相互之间是不能共享的。
拿SGA中两个最重要的内存区Buffer Cache和Shared Pool来说,它们两个对实例的性能影响最大,
但是就有这样的矛盾存在:在内存资源有限的情况下,某些时候数据被cache的需求非常大,
为了提高buffer hit,就需要增加Buffer Cache,但由于SGA有限,只能从其他区“抢”过来——如缩小Shared Pool,
增加Buffer Cache;而有时又有大块的PLSQL代码被解析驻入内存中,导致Shared Pool不足,
甚至出现4031错误,又需要扩大Shared Pool,这时可能又需要人为干预,从Buffer Cache中将内存夺回来。
& & & &&有了这个新的特性后,SGA中的这种内存矛盾就迎刃而解了。这一特性被称为自动共享内存管理
(Automatic Shared Memory Management ASMM)。而控制这一特性的,也就仅仅是这一个参数SGA_TARGE。
设置这个参数后,你就不需要为每个内存区来指定大小了。SGA_TARGET指定了SGA可以使用的最大内存大小,
而SGA中各个内存的大小由Oracle自行控制,不需要人为指定。Oracle可以随时调节各个区域的大小,使之达到系
统性能最佳状态的个最合理大小,并且控制他们之和在SGA_TARGET指定的值之内。一旦给SGA_TARGET指定值后
(默认为0,即没有启动ASMM),就自动启动了ASMM特性。
三、oracle 内存调优办法
当项目的生产环境出现性能问题,我们如何通过判断那些参数需要调整呢?
3.1 检查ORACLE实例的Library Cache命中率:
标准:一般是大于99%
检查方式: select 1-(sum(reloads)/sum(pins)) "Library cache Hit Ratio" from v$
如果Library cache Hit Ratio的值低于99%,应调高shared_pool_size的大小。通过sqlplus连接数据库执行如下命令,调整shared_pool_size的大小:
SQL&alter system flush shared_
SQL&alter system set shared_pool_size=设定值 scope=
3.2 检查ORACLE实例的Data Buffer(数据缓冲区)命中率:
标准:一般是大于90%
&&& select 1 - (phy.value / (cur.value + con.value)) "HIT RATIO"
&&& from v$sysstat cur, v$sysstat con, v$sysstat phy
&&& where cur.name = 'db block gets'
&&& and con.name = 'consistent gets'
&&&& and phy.name = 'physical reads';
如果HIT RATIO的值低于90%,应调高db_cache_size的大小。通过sqlplus连接数据库执行如下命令,
调整db_cache_size的大小
SQL&alter system set db_cache_size=设定值 scope=spfile
3.3&检查ORACLE实例的Dictionary Cache命中率:
标准:一般是大于95%
select 1 - (sum(getmisses) / sum(gets)) "Data Dictionary Hit Ratio"& from v$
如果Data Dictionary Hit Ratio的值低于95%,应调高shared_pool_size的大小。通过sqlplus连接数据库执行如下命令,调整shared_pool_size的大小:
SQL&alter system flush shared_
SQL&alter system set shared_pool_size=设定值 scope=
3.4 &检查ORACLE实例的Log Buffer命中率:
标准:一般是小于1%
&&& select (req.value * 5000) / entries.value "Ratio"
&&&&& from v$sysstat req, v$sysstat entries
&&&& where req.name = 'redo log space requests'
&&&&& and entries.name = 'redo entries';
如果Ratio高于1%,应调高log_buffer的大小。通过sqlplus连接数据库执行如下命令,调整log_buffer的大小:
SQL&alter system set log_buffer=设定值 scope=
3.5&检查undo_retention:
标准:undo_retention 的值必须大于max(maxquerylen)的值
col undo_retention format a30
select value "undo_retention" from v$parameter where name='undo_retention';
select max(maxquerylen) From v$undostat Where begin_time&sysdate-(1/4);
如果不满足要求,需要调高undo_retention 的值。通过sqlplus 连接数据库执行如下命
令,调整undo_retention 的大小:
SQL&alter system set undo_retention= 设定值 scope=
32bit &和 64bit &的问题
对于 oracle 来说,存在着 32bit 与 64bit 的问题。这个问题影响到的主要是 SGA 的大小。在 32bit
的数据库下,通常 oracle 只能使用不超过 1.7G 的内存,即使我们拥有 12G 的内存,但是我们却只能使用
1.7G,这是一个莫大的遗憾。假如我们安装 64bit 的数据库,我们就可以使用很大的内存,我们几乎不可能达到上限。但是 64bit
的数据库必须安装在 64bit 的操作系统上,可惜目前 windows 上只能安装 32bit 的数据库. 但是在特定的操作系统下,可能提供了一定的手段,使得我们可以使用超过 1.7G 的内存,达到 2G 以上甚至更多。
=================补充=======================
Oracle数据库包含了如下基本内存组件
System global area (SGA)
The SGA is a group of shared memory structures, known as&SGA components,
that contain data and control information for one Oracle Database
instance. The SGA is shared by all server and background processes.
Examples of data stored in the SGA include cached data blocks and shared
SQL areas.
Program global area (PGA)
A PGA is a
nonshared memory region that contains data and control information
exclusively for use by an Oracle process. The PGA is created by Oracle
Database when an Oracle process is started.
One PGA exists for each&&and background process. The collection of individual PGAs is the&total instance PGA, or&instance PGA. Database initialization parameters set the size of the instance PGA, not individual PGAs.
User Global Area (UGA)
The UGA is memory associated with a user session.
Software code areas
code areas are portions of memory used to store code that is being run
or can be run. Oracle Database code is stored in a software area that is
typically at a different location from user programs—a more exclusive
or protected location.
Oracle依赖于内存相关的初始化参数来控制内存的管理。
内存管理有如下三个选项
Automatic memory management
specify the target size for instance memory. The database instance
automatically tunes to the target memory size, redistributing memory as
needed between the SGA and the instance PGA.
Automatic shared memory management
management mode is partially automated. You set a target size for the
SGA and then have the option of setting an aggregate target size for the
PGA or managing PGA work areas individually.
Manual memory management
of setting the total memory size, you set many initialization
parameters to manage components of the SGA and instance PGA
individually.
UGA是会话内存,用来保存会话变量例如登录信息,已经数据库会话需要的其他信息。
当PL/SQL包加载进内存时,UGA中包含了package state,也就是调用PL/SQL时指定的变量值。
PGA缓冲区,则主要是为了某个用户进程所服务的。这个内存区不是共享的,只有这个用户的服务进程本身才能够访问它自己的PGA区。做个形象的比喻,SGA就好像是操作系统上的一个共享文件夹,不同用户可以以此为平台进行数据方面的交流。而PGA就好像是操作系统上的一个私有文件夹,只有这个文件夹的所有者才能够进行访问,其他用户都不能够访问。虽然程序缓存区不向其他用户的进程开放,但是这个内存区仍然肩负着一些重要的使命,如数据排序、权限控制等等都离不开这个内存区。
私有SQL区包含了绑定变量值和运行时期内存结构信息等数据。每一个运行SQL语句的会话都有一个块私有SQL区。一个游标的私有SQL区又分为两个生命周期不同的区:
永久区,包含绑定变量信息。当游标关闭时被释放。
运行区,当执行结束时释放。
A&cursor&is a name or&handle to a specific private SQL area
SGA包含如下组件
Database Buffer Cache
Redo Log Buffer
Shared Pool
Large Pool
Streams Pool
Buffer cache
Buffer Cache是SGA区中专门用于存放从数据文件中读取的的数据块的区域。Oracle进程如果发现需要访问的数据块已经在buffer cache中,就直接读写内存中的相应区域,而无需读取数据文件,从而大大提高性能。Buffer cache对于所有oracle进程都是共享的,即能被所有oracle进程访问。
Buffer的大小和数据块一样。
Buffer cache按照类型分为3个池
Default pool
pool is the location where blocks are normally cached. Unless you
manually configure separate pools, the default pool is the only buffer
This pool is intended for blocks
that were accessed frequently, but which aged out of the default pool
because of lack of space. The goal of the keep buffer pool is to retain
objects in memory, thus avoiding I/O operations.
Recycle pool
pool is intended for blocks that are used infrequently. A recycle pool
prevent objects from consuming unnecessary space in the cache.
Oracle还提供了非标准块大小的buffer cache。如果你建立的表空间指定的块大小为非数据库块大小,那么将使用这些buffer cache来缓存数据块。
首先Oracle 以每个数据块的文件号、块号、类型做hash运算,得到hash值。
对于hash值相同的块,放在一个Hash Bucket中。
因为buffer的大小毕竟有限,buffer中的数据块需要根据一定的规则提出内存。
Oracle采用了LRU算法维护一个LRU链表,来决定哪些数据块被淘汰。
通用的淘汰算法如下
Oracle改进了LRU算法,引入了Touch count概念、以及LRU链表分为热端头和冷端头。
Touch count:
&用来记录数据块访问的频繁度,此数值在内存中不受保护,多个进程可以同时修改它。这个值并不是精准的表示块被访问的次数,只是一种趋势。3秒内无论多少用户,访问多少次块。此值加1.
当数据块第一次被放到buffer中,Oracle将其放置在冷端的头部。
如果buffer已经没有空闲空间,那么如何淘汰数据块呢?Oracle从LRU的冷端尾部扫描数据块,当发现数据块的Touch
count大于等于2时,将数据块移动到热端头部,并将Touch count置为0 。当Oracle发现Touch
count小于2时,则淘汰该数据块。
当数据块被修改了,我们把这个块称之为脏块。脏块在写入磁盘前,是不会被踢出buffer的。
如果LRU中的脏块比较多,每次申请新的空间时,都要扫描很多脏块,但是又不能被淘汰。效率很低。
为此Oracle因为了脏LRU链表。专门用来记录脏数据块。
当块被修改,并不会马上从LRU链表中移动到LRUW中。只有当Oracle需要淘汰数据块时,才会去扫描LRU链表,此时发现块为脏块,将数据块移动到LRUW链表中。
检查点链表
通过上面的描述,我们知道脏块在LRU和LRUW链表中都有。那么当dbwr写数据时,这两个链表都要扫描。首先效率比较低,并且无法保证先修改的数据块先被写入磁盘。
为此Oracle引入了检查点队列,该队列按照数据块第一次被修改顺序将脏块链接到一起。
dbwr写脏块时,只需读取检查点队列即可。
并且每个数据块与记录了日志条目的位置
redo log buffer
用户进程将redo entries 拷贝到redo log buffer中。LGWR负责将其写到磁盘中。
Redo entries&contain
the information necessary to reconstruct, or redo, changes made to the
database by DML or DDL operations. Database recovery applies redo
entries to data files to reconstruct lost changes.
Library Cache:
主要存放shared curosr(SQL)和PLSQL对象(function,procedure,trigger)的信息,以及这些对象所依赖的table,index,view等对象的信息。
Private SQL Areas与Shared SQL Area的关系
数据字典缓存
用来缓存系统数据字典表的内容,与普通表的缓存不同,普通表以块为单位缓存到buffer cache中。而数据字典缓存以行为单位,缓存到shared pool中的data dictionary cache中。
Server result cache
用来缓存sql或者plsql的执行结果。
&The large pool can provide large memory allocations for the following:
UGA for the&shared server and&the&&interface (used where transactions interact with multiple databases)
Message buffers used in the parallel execution of statements
Buffers for Recovery Manager (RMAN) I/O slaves
Oracle提供了两个初始化参数用来配置内存自动管理
MEMORY_TARGET:sga+pga内存之和,Oracle自动分配SGA和PGA的大小。
MEMORY_MAX_TARGET:MEMORY_TARGET可以设置大小的上限。
SGA自动内存管理
设置初始化参数SGA_TARGET为非0值,并且将STATISTICS_LEVEL的值设置为TYPICAL或者ALL.
PGA自动内存管理
PGA_AGGREGATE_TARGET设置为非0值。
如果workarea_size_policy为auto则sort_area_size,hash_area_size等参数设置被忽略,如果workarea_size_policy为manual,则sort_area_size,hash_area_size等参数设置生效。
也可以手工配置其他各个内存池的大小。当配置了内存自动管理时,有配置了具体池的大小,那么该配置为自动内存分配时的最小大小。
查看内存情况
The following views provide information about dynamic resize operations:
V$MEMORY_CURRENT_RESIZE_OPS&displays information about memory resize operations (both automatic and manual) which are currently in progress.
V$MEMORY_DYNAMIC_COMPONENTS&displays
information about the current sizes of all dynamically tuned memory
components, including the total sizes of the SGA and instance PGA.
V$MEMORY_RESIZE_OPS&displays
information about the last 800 completed memory resize operations (both
automatic and manual). This does not include in-progress operations.
V$MEMORY_TARGET_ADVICE&displays tuning advice for the&MEMORY_TARGET&initialization parameter.
V$SGA_CURRENT_RESIZE_OPS&displays
information about SGA resize operations that are currently in progress.
An operation can be a grow or a shrink of a dynamic SGA component.
V$SGA_RESIZE_OPS&displays
information about the last 800 completed SGA resize operations. This
does not include any operations currently in progress.
V$SGA_DYNAMIC_COMPONENTS&displays
information about the dynamic components in SGA. This view summarizes
information based on all completed SGA resize operations that occurred
after startup.
V$SGA_DYNAMIC_FREE_MEMORY&displays information about the amount of SGA memory available for future dynamic SGA resize operations.
&&&回复&&&:
北京盛拓优讯信息技术有限公司. 版权所有 京ICP备号 北京市公安局海淀分局网监中心备案编号:10
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员

我要回帖

更多关于 java学到什么程度才能找到工作 的文章

 

随机推荐