您的位置:首页 > 编程语言 > Java开发

Java 内存模型

2012-02-01 12:38 288 查看
Java内存模型中的三个代

Java的内存模型由3个代组成,各个代的默认排列有如下图(适用JDK1.4.* 到 JDK6):



Java 的内存模型分为 Young(年轻代) Tenured(终身代) Perm(永久代)

有些旧版本也叫作 New Old Perm

叫法不同,表达的意思却是基本相同。

注意Young(年轻代)还可以分为Eden区和两个Survivor区(from和to,这两个Survivor区大小严格一至),新的对象实例总是首先放在Eden区,Survivor区作为Eden区和
Tenure(终生代)的缓冲,可以向
Tenure(终生代)转移活动的对象实例。

Tenure(终生代)中存放生命周期长久的实例对象,但并不是如它的名字那样是终生的,里面的对象照样会被回收掉。

Young和Tenure共同组成了堆内存。

Perm(永久代)则是非堆内存的组成部分。主要存放加载的Class类级对象如class本身,method,field等等。

有同学可能已经注意到了,每个代都有的Virtual区又是什么?

我们知道有一些参数可以影响以上各代的大小。

在JVM启动时,就已经保留了固定的内存空间给Heap内存,这部分内存并不一定都会被JVM使用,但是可以确定的是这部分保留的内存不会被其他进程使用。这部分内存大小由
-Xmx
参数指定。


而另一部分内存在JVM启动时就分配给JVM,作为JVM的初始Heap内存使用。影响这个的参数是 -Xms ,如果
-Xms 指定的值比-Xmx 的小,那么两者的差值就是Virtual内存值。随着程序的运行,Eden区、 Tenured区和Perm区会逐渐使用保留的Virtual空间。

如果没有具体指定,初始和最大堆内存将根据机器的内存计算得出。参数
DefaultInitialRAMFraction

DefaultMaxRAMFraction
会影响最终的结果,如下表所示:

FormulaDefault
initial heap size
memory / DefaultInitialRAMFraction
memory /
64
maximum heap size
MIN(memory / DefaultMaxRAMFraction, 1GB)
MIN(memory
/ 4, 1GB)
可以看到堆内存默认值最大不会超过1G。

JVM会根据堆内存的使用情况自动决定何时扩张和缩减实际堆内存的大小,可以用VM参数
-XX:MinHeapFreeRatio=<minimum>

-XX:MaxHeapFreeRatio=<maximum> 使用堆内存空闲百分比来定义,一般在32位机器上的默认值如下:


ParameterDefault Value
MinHeapFreeRatio
40
MaxHeapFreeRatio
70
-Xms
3670k
-Xmx
64m
当空闲堆内存所占堆内存百分比低于40%,JVM就会试图扩张堆内存空间;当空闲堆内存所占堆内存百分比高于70%,JVM就会试图压缩堆内存空间。

ps:以上默认值在不同平台会有不同的值,如果是64位系统,这些值一般需要扩张30%,来容纳在64位系统下变大的对象。

加上
-XX:NewRatio=3
意味着 young(年轻代) 和 tenured(终生代)的比率是1:3,也就是说,eden区和survivor区容量之和将占总堆内存的1/4。

加上-XX:SurvivorRatio=6
设置eden区和 其中一个survivor space的比率是1:6,也就是说,其中一个survivor space占年轻代1/8的容量 (可以想想为什么不是1/7)。

另外还有
-XX:NewSize
-XX:MaxNewSize   指定年轻代的初始值和最大值。


32位系统下默认值如下:

Default Value
ParameterClient JVMServer JVM
NewRatio
8
2
NewSize
2228K
2228K
MaxNewSize
not limited
not limited
SurvivorRatio
32
32
==============================================================================

1、 PermGen space的全称是Permanent Generation space,是指内存的永久保存区域OutOfMemoryError: PermGen space从表面上看就是内存益出,解决方法也一定是加大内存。说说为什么会内存益出:这一部分用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen
space错误。这种错误常见在web服务器对JSP进行pre compile的时候。改正方法:-Xms256m -Xmx256m -XX:MaxNewSize=256m -XX:MaxPermSize=256m

2、在tomcat中redeploy时出现outofmemory的错误. 可以有以下几个方面的原因:

1,使用了proxool,因为proxool内部包含了一个老版本的cglib.

2, log4j,最好不用,只用common-logging

3, 老版本的cglib,快点更新到最新版。

4,更新到最新的hibernate3.2

3、这里以tomcat环境为例,其它WEB服务器如jboss,weblogic等是同一个道理。

一、java.lang.OutOfMemoryError: PermGen space PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的应用中有很多CLASS的话,就很可能出现PermGen
space错误,这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。解决方法: 手动设置MaxPermSize大小修改TOMCAT_HOME/bin/catalina.sh在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:J***A_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m建议:将相同的第三方jar文件移置到tomcat/shared/lib目录下,这样可以达到减少jar
文档重复占用内存的目的。

二、java.lang.OutOfMemoryError: Java heap spaceHeap size 设置JVM堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置.JVM在启动的时候会自动设置Heap size的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。Heap size 的大小是Young Generation 和Tenured Generaion 之和。提示:在JVM中如果98%的时间是用于GC且可用的Heap
size 不足2%的时候将抛出此异常信息。提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。 解决方法:手动设置Heap size修改TOMCAT_HOME/bin/catalina.sh在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:J***A_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m"

三、实例,以下给出1G内存环境下java jvm 的参数设置参考: J***A_OPTS="-server -Xms800m -Xmx800m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -Djava.awt.headless=true "



我在使用liferay用mysql数据库的时候碰到了该问题,最后的解决方法是在

TOMCAT_HOME/bin/catalina.sh在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:J***A_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m"

==============================================================================

SUN JDK中关于Permanent Generation(永久代)的几个问题

in Java性能优化

永久代的大小是如何变化的?
The permanent generation is used to hold reflective of the VM itself such as class objects and method objects. These reflective
objects are allocated directly into the permanent generation, and it is sized independently from the other generations. Generally, sizing of this generation can be ignored because the default size is adequate. However, programs that load many classes
may need a larger permanent generation.

如何知道永久代是否已满?

     Starting in 1.4.2 -XX:+PrintGCDetails will print information about all parts of the heap collected at each garbage collection. For a full collection

[Full GC [Tenured: 30437K->33739K(280576K), 0.7050569 secs] 106231K->33739K(362112K), [Perm : 2919K->2919K(16384K)], 0.7052334 secs]

this example shows that little was collected in the permanent generation (it went from 2919K used before the collection to 2919K used after the collection) and the current size of the permanent generation is 16384K.

如何增加永久代大小?

Use the command line option -XX:MaxPermSize=<desired size>

如何知道加载或卸载了哪些类?

Use the command line options -XX:+TraceClassloading and -XX:+TraceClassUnloading

是否在client vm中增加永久代大小?

This will always be a judgment
call. In general increasing the size of a generation (and this applies not just to the permanent generation) can reduce the incidence of a wide variety of problems However, this may cause other processes to excessively page and/or garbage collect or
throw out-of-memory exceptions.
There are two failure modes to consider.
When raising MaxPermSize, it is possible that previously well behaved programs that used to garbage collect to recover the permanent generation space will die by endless paging. For the permanent generation this
usually only happens with the heavy interning of temporary strings.

The other failure mode is that address space must be reserved for the permanent generation and this will reduce that available for the rest of the heap (the maximum -Xmx may then be too large). This will cause
programs configured to use all available space to fail at initialization.

==============================================================================
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: