`
wxb_j2ee
  • 浏览: 138641 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

有关Java内存溢出及内存消耗的小知识

    博客分类:
  • java
阅读更多
内存溢出原理:
我们知道,Java程序本身是不能直接在计算机上运行的,它需要依赖于硬件基础之上的操作系统和JVM(Java虚拟机)。

Java程序启动时JVM都会分配一个初始内存和最大内存给这个应用程序。这个初始内存和最大内存在一定程度上会影响应用程序的性能。

JVM其实就是操作系统上的一个普通程序(进程名叫java,这个程序可以解释执行class文件,系统中当前运行了多少个java程序就会有多少个java进程)。

当Java进程启动时会首先分配一块堆内存(最小内存),以后每当java程序要求JVM(java进程)分配内存时,JVM就会在预先分配的那块内存上为java程序分配内存,当预先分配的那块内存用完时,JVM会再向操作系统要内存(物理内存),但是JVM不会无限制的向操作系统要内存,当它占用的实际内存达到一个预定值(最大可用内存)时,如果Java程序还向JVM要内存,并且JVM无法通过垃圾回收机制回收当前堆中的内存来为java程序服务时,它就会给程序抛出异常:java.lang.OutOfMemoryError。
其中内存回收时机并不是在用掉内存达到最大可用内存时才进行,它的运行时机是不确定的。可见JVM的最大可用内存就是java程序能够使用的最大内存。
例如:
我们把某JAVA程序的JVM最大可用内存设为200M,而我们的物理内存是1G。
这种情况下,我们的java程序最多能使用200M内存,虽然我们可能还有800M的内存可用,但是当我们的程序用掉200M后,如果再要内存,JVM不会因为我们还有800M的内存而为我们分配内存,它会抛出java.lang.OutOfMemoryError异常。



Runtime.getRuntime().totalMemory() :返回 Java 虚拟机中的内存总量。
Runtime.getRuntime().maxMemory()   :返回 Java 虚拟机试图使用的最大内存量。
Runtime.getRuntime().freeMemory()  :返回 Java 虚拟机中的空闲内存量。
单位是字节(Byte)

1024Byte(字节)=1KB
1024KB=1MB
1024MB=1GB
1024GB=1TB


Tomcat服务器的例子:

1.java.lang.OutOfMemoryError: PermGen space

PermGen space的全称是Permanent Generation space,是指内存的永久保存区域OutOfMemoryError: PermGen space。从文字上看就是内存溢出,解决方法是加大内存。为什么会内存溢出,这是由于这块内存主要是被JVM存放Class和Meta信息的,Class在被Load的时候被放入PermGen space区域,它和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。

解决方法: 手动设置MaxPermSize大小

修改TOMCAT_HOME/bin/catalina.sh
在“echo "Using CATALINA_BASE:    $CATALINA_BASE"”上面加入以下行:
JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m

建议:将相同的第三方jar文件移置到tomcat/shared/lib目录下,这样可以达到减少jar 文档重复占用内存的目的。

2.java.lang.OutOfMemoryError: Java heap space

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

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

提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。

Tomcat默认可以使用的内存为128MB,在较大型的应用项目中,这点内存是不够的,需要调大。有以下几种方法可以选用:

第一种方法:
Windows下,在文件/bin/catalina.bat,Unix下,在文件/bin/catalina.sh的前面,增加如下设置:
JAVA_OPTS='-Xms【初始化内存大小】 -Xmx【可以使用的最大内存】'
需要把这个两个参数值调大。例如:
JAVA_OPTS='-Xms256m -Xmx512m'
表示初始化内存为256MB,可以使用的最大内存为512MB。


第二种方法:
环境变量中设     变量名:JAVA_OPTS     变量值:-Xms512m   -Xmx512m


第三种方法:
前两种方法针对的是bin目录下有catalina.bat的情况(比如直接解压的Tomcat等),但是有些安装版的Tomcat下没有catalina.bat,这个时候可以采用如下方法,当然这个方法也是最通用的方法:打开tomcatHome/\bin/\tomcat5w.exe,点击Java选项卡,然后将会发现其中有这么两项:Initial memory pool和Maximum memory pool.Initial memory pool这个就是初始化设置的内存的大小。Maximum memory pool这个是最大内存的大小 设置完了就按确定然后再重启TOMCAT你就会发现tomcat中jvm可用的内存改变了

另外需要考虑的是Java提供的垃圾回收机制。虚拟机的堆大小决定了虚拟机花费在收集垃圾上的时间和频度。收集垃圾可以接受的速度与应用有关,应该通过分析实际的垃圾收集的时间和频率来调整。如果堆的大小很大,那么完全垃圾收集就会很慢,但是频度会降低。如果你把堆的大小和内存的需要一致,完全收集就很快,但是会更加频繁。调整堆大小的的目的是最小化垃圾收集的时间,以在特定的时间内最大化处理客户的请求。在基准测试的时候,为保证最好的性能,要把堆的大小设大,保证垃圾收集不在整个基准测试的过程中出现。
如果系统花费很多的时间收集垃圾,请减小堆大小。一次完全的垃圾收集应该不超过 3-5 秒。如果垃圾收集成为瓶颈,那么需要指定代的大小,检查垃圾收集的详细输出,研究 垃圾收集参数对性能的影响。一般说来,你应该使用物理内存的 80% 作为堆大小。当增加处理器时,记得增加内存,因为分配可以并行进行,而垃圾收集不是并行的。

一个要注意的地方:建议把内存的最高值跟最低值的差值缩小,不然会浪费很多内存的, 最低值加大 ,最高值可以随便设,但是要根据实际的物理内存 ,如果内存设置太大了,比如设置了512M最大内存,但如果没有512M可用内存,Tomcat就不能启动,还有可能存在内存被系统回收,终止进程的情况。



分享到:
评论
4 楼 zjuttsw 2013-02-27  
wxb_j2ee 写道
zjuttsw 写道
我记得好像就这几个:Young Generation(含有Eden和两个Survivor)。Old Generation以及Permanent Generation. 不记得怎么还有Tenured generation.

http://eyesmore.iteye.com/blog/1400249
Tenured generation 其实就是  Old Generation 叫法而已。
找了一个文章。分享给你。比喻的很恰当。

原来如此。
3 楼 wxb_j2ee 2013-02-27  
zjuttsw 写道
我记得好像就这几个:Young Generation(含有Eden和两个Survivor)。Old Generation以及Permanent Generation. 不记得怎么还有Tenured generation.

http://eyesmore.iteye.com/blog/1400249
Tenured generation 其实就是  Old Generation 叫法而已。
找了一个文章。分享给你。比喻的很恰当。
2 楼 zjuttsw 2013-02-06  
我记得好像就这几个:Young Generation(含有Eden和两个Survivor)。Old Generation以及Permanent Generation. 不记得怎么还有Tenured generation.
1 楼 zjuttsw 2013-02-06  

很好。就是有一点不懂,Young Generation我知道是年轻代,请问Tenured Generation是什么?

相关推荐

    内存溢出配置,内存溢出配置

    内存溢出配置是IT行业中,尤其是在Java应用开发与运维领域中的一个重要话题,它涉及到系统资源管理、性能调优以及故障排查等多个方面。标题与描述中重复提到“内存溢出配置”,这表明了对这一主题的关注与重视。接...

    内存泄漏与内存溢出

    在软件开发领域,尤其是涉及到数据库应用的场景下,内存泄漏(Memory Leak)和内存溢出(Out of Memory,简称OOM)是两个常见的问题,它们直接影响到程序的性能、稳定性和可扩展性。以下是对这两个概念及其相关知识...

    myeclipse内存溢出问题解决方案

    本文主要讨论如何解决MyEclipse中的内存溢出问题以及相关的Java内存管理知识点。 首先,解决内存溢出问题的关键在于调整JVM的内存配置。在MyEclipse中,可以通过以下路径进行设置:Window > Preferences > ...

    解决jetty8内存溢出版本

    Jetty 8是一款轻量级、高性能的Java Web服务器和Servlet容器,被广泛用于开发、测试和部署Web应用程序。...通过对上述知识点的理解和实践,可以有效地预防和解决Jetty 8的内存溢出问题,提高服务的稳定性和性能。

    PIO导入大量数据时的解决内存溢出问题.doc

    PIO 导入大量数据时的解决内存溢出问题的知识点: 1. 使用 EventUserModel 模式来避免内存溢出问题。 2. 使用 HSSFListener 接口来处理每个单元格的数据。 3. 使用 optRows 方法来对行级数据进行操作。 4. 使用抽象...

    cpu利用率过高,内存溢出分析

    其次,内存溢出(Memory Leak)是指程序在申请内存后,无法释放已申请的内存空间,一次小的内存泄漏可能不明显,但随着时间推移,累积的内存泄漏会消耗大量内存,导致系统性能下降甚至崩溃。内存溢出通常与编程语言...

    内存溢出问题修改

    #### 知识点一:理解内存溢出问题 内存溢出(Out of Memory)是指程序在运行过程中申请的内存超过了系统能提供的最大内存限制时,程序会抛出异常,导致应用崩溃或者无法正常运行。这种现象在Java等面向对象的编程...

    解决poi读取excel2007出现内存溢出问题代码参

    在处理大型Excel 2007(.xlsx)文件时,Apache POI是一个常见的Java库,但不恰当的使用方式可能会导致内存溢出错误。这是因为POI默认会将整个工作簿加载到内存中,对于大文件,这显然是不可行的。为了解决这个问题,...

    介绍堆栈,线程 如何解决内存溢出

    1. **优化数据结构**:选择更高效的数据结构可以减少内存消耗,例如使用哈希表代替链表,减少内存开销。 2. **内存池**:通过预先分配一大块内存并管理这些内存的分配和释放,可以避免频繁的内存申请和释放操作,...

    MAT解析hprof内存溢出分析工具OutOfMemoryError-java程序开发

    MAT(Memory Analyzer Tool)是IBM提供的一款强大的Java内存分析工具,它专为解决此类问题而设计,帮助开发者深入理解内存消耗,有效地定位内存泄漏和性能瓶颈。 MAT的使用方法和功能详解: 1. **数据获取**:首先...

    用于本机内存溢出分析工具(原)

    标题中的“用于本机内存溢出分析工具(原)”暗示了这个压缩包可能包含一个原始的、专门用于分析本地计算机内存溢出问题的工具。内存溢出是编程和系统管理中常见的问题,通常发生在程序试图分配超过可用内存时。这种...

    Java堆栈内存分析笔记

    2. **MAT (Memory Analyzer Tool)**:IBM开发的内存分析工具,能帮助定位内存泄漏,提供详细的内存消耗报告。 3. **JConsole**:另一个JDK自带的工具,用于监视JVM的性能,包括内存使用情况。 4. **代码优化**:...

    JAVA技巧(Java多线程运行时,减少内存占用量).pdf

    文件内容并不完整,且存在 OCR 扫描错误,但我会尝试从中提取与Java多线程和内存管理相关的知识点,并加以详细解释。 ### Java多线程运行时的内存管理 在Java中,多线程是实现并行计算的核心机制之一,而内存管理...

    Android 图片下载以及内存处理防止OOM内存溢出 源码

    在Android开发中,图片的加载和内存管理是一个关键问题,特别是考虑到防止因内存溢出(Out Of Memory,简称OOM)而导致应用崩溃。本教程将详细探讨如何在Android中有效地进行图片下载和内存处理,以避免OOM的发生。 ...

    基于Java虚拟机内存模型的性能调优方法.zip

    - **类加载器**:控制类的加载、验证、准备、解析和初始化过程,优化类加载策略可减少内存消耗。 5. **JVM调优工具** - **JConsole**:提供实时监控和诊断JVM状态的工具,包括内存、线程、类装载等信息。 - **...

    精选_毕业设计_基于JAVA的内存管理模拟_完整源码

    7. **内存溢出与内存泄漏**:内存溢出(Out Of Memory, OOM)是由于程序申请的内存超过了系统能提供的,导致JVM无法运行。内存泄漏是程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,导致系统内存不断...

    java入门、java内存区域和OOM、垃圾回收器和垃圾回收策略

    本教程将涵盖Java的基础知识,特别是关于内存管理的重要概念——Java内存区域、Out of Memory (OOM)错误以及垃圾回收器和垃圾回收策略。 1. **Java入门**: Java的学习始于基础语法,包括变量、数据类型、运算符、...

    基于Java的内存泄露分析及定位

    #### Java内存泄露背景知识 **JVM内部体系结构** Java虚拟机(JVM)是Java运行环境的核心部分,它负责执行Java字节码。JVM主要由类加载器子系统、运行时数据区、执行引擎和本地接口等组成。其中,运行时数据区包括...

    Android应用源码之防止内存溢出浅析.zip

    通过对以上知识点的深入理解和实践,开发者可以有效防止Android应用出现内存溢出问题,提升应用的稳定性和性能。在实际开发中,我们需要不断学习和掌握新的内存管理策略,以应对日益复杂的Android生态环境。

Global site tag (gtag.js) - Google Analytics