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

Java应用中你可能会遇到的各种不同的OutofMemoryError类型(未完待续)

2011-06-15 22:02 561 查看
当Java虚拟机没有足够的空间来创建新对象是,Java应用就会抛出“OutOfMemoryError ”。你可能会遇到几种不同的“OutOfMemory”,在这篇文章中让我们来看一下将会在你的Java应用中发生的各种OutOfMemoryError



在你的应用中将会产生如下几种Out-Of-Memory-Errors:

Heap Memory Error(堆内存错误)
Non-heap memory Error(非堆内存错误)
Native memory error(本地内存错误)

堆内存错误

java.lang.OutOfMemoryError: Java heap space

堆内存是Java运行时存放所有的类实例数组的数据区域。堆内存是动态扩展的。当一个Java应用启动是,堆内存将会初始化为默认的最小值。当新的对象创建时,将会分配堆内存。如果堆内存不够创建新对象,它会自动扩展一定数量。堆内存将会一直扩展,直到默认的最大值。

默认的堆最小和最大是是2M64M。在服务器模式下,默认的大小分别是是32M128M(JVM可以通过参数 -server 跑在服务器模式)

你可以通过以下参数来设定堆最小值和最大值

比如-Xms32m 表示设定的最小值是32Mbytes
比如-Xmx128m 表示设定的堆最大值为128Mbytes

堆内存溢出的原因是各种各样的。一个简单的原因是你的应用很大,默认的堆大小已经不能满足了,在这种情况下,你可以通过 Xms 和 Xmx设定最大值和最小值。

另一个原因是你的应用有一些内存泄漏。在Java中,一旦内存被分配给一些对象,这些内存就会被一个叫垃圾回收的程序来回收。垃圾回收只能回收那些不再被使用的对象。如果你的对象已经不再被使用了,但是却被引用了,那么垃圾回收就不会回收这个对象。诊断垃圾回收会是相当困难的。你可以使用分析工具(profiling tool)像Optimize IT(yourkit, jconsole)来诊断内存泄漏。

非堆内存错误

java.lang.OutOfMemoryError: PermGen space

在Java虚拟机中,内存被分为几块区域,其中的一块叫PermGen(全称是Permanent Generation space,是指内存的永久保存区域)。这块区域是用来装载类文件的。不像堆内存空间,这块内存区域的大小是固定的,不会在Java虚拟机运行的时候改变。你可以在命令行中使用参数 –XX:MaxPermSize 来指定这块区域的大小。SUN 虚拟机默认的大小是64M

如果垃圾回收有问题,而且你一直不断地加载新的类,这块内存区域就会耗尽,即使堆内存还有很大的空间。设置参数-Xmx对这块区域没什么任何帮助:这个参数只设置总的堆大小,不会对PermGen产生影响。

造成PermGen错误的原因主要是你加载了太多的类,在这种情况下你可以通过上述的参数(–XX:MaxPermSize )来增加PermGen的空间。

也有可能你使用了多个classloader,造成了一个class在内存中被重复加载。这种情况出现在没有重启服务器的情况下部署了网络应用(Web application)

像Glassfish这样的应用服务器(Application Server)允许你开发、打包(.ear, .war等)、发布一个应用到服务器(已经有其他应用在运行)上。你可以很方便的做修改、编译代码、重新发布到服务器而不会影响正在运行的其他应用:你不必重启服务器。这种机制在Glassfish和其他一些应用服务器(比如:Java CAPS Integration Server)上运行得很好。

这种工作方式的原理是每一个应用都用自己的classloader来加载。简单来说,一个classloader是一个特殊的类,功能是从jar文件中加载.class文件。当你卸载应用的时候,classloader被丢弃,所有它加载的类都早晚会被垃圾回收。

然而,一些东西可能将classloader挂起,阻止它被垃圾回收。这就是为什么产生java.lang.OutOfMemoryError: PermGen space exception的原因了。此类问题解决起来非常棘手,阅读这篇blog 来获得更多的信息。

Native memory error

Whether it is heap space or permgen space, finally everything has to be allocated by the Operating System either in the RAM or in the Virtual Memory. What happens if the entire Virtual Memory is full? The OS may fail to allocate memory to the JVM. In this
case a native memory error will be thrown like:

java.lang.OutOfMemoryError: request <size> bytes for <reason>.

Out of swap space?

The reason can be that the virtual memory set in the OS is too low or you have many other applications running which are consuming lots of memory. In either case, you can try increasing the virtual memory. The procedure for increasing the virtual memory
can vary from OS to OS.

In Windows, the VirtualMemory is allocated as a pagefile on the disk. When the virtual memory is full, windows will automatically increase the virtual memory and give a message “Windows is increasing your virtual memory, during this process; memory requests
by some applications may be denied”.

You can also increase the virtual memory in windows manually. Read
here for the steps.

Increasing the virtual/swap memory in unix/linux flavor operating systems can be difficult because in these operating systems, the virtual memory is allocated on a separate partition called swap partition. You will need to provide an additional swap partition
or resize the existing swap partition. Read
here for the steps

There are also some special cases then Out-Of-Memory may be thrown. For example the toArray method in Collection cannot convert from the collection to array if the number of elements is more than Integer.MAX_VALUE. In that case you will get

原文地址:http://javabyexample.wisdomplug.com/java-concepts/34-core-java/60-different-types-of-outofmemoryerror-you-can-encounter-in-your-java-application.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐