JVM管理两种类型的内存,堆和非堆。堆是给开发人员用的上面说的就是,是在JVM启动时创建;非堆是留给JVM自己用的,用来存放类的信息的。它和堆不同,运行期内GC不会释放空间。
一、内存溢出类型
1、java.lang.OutOfMemoryError: PermGen space
JVM管理两种类型的内存,堆和非堆。堆是给开发人员用的上面说的就是,是在JVM启动时创建;非堆是留给JVM自己用的,用来存放类的信息的。它和堆不同,运行期内GC不会释放空间。如果web app用了大量的第三方jar或者应用有太多的class文件而恰好MaxPermSize设置较小,超出了也会导致这块内存的占用过多造成溢出,或者tomcat热部署时侯不会清理前面加载的环境,只会将context更改为新部署的,非堆存的内容就会越来越多。
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)那么就会产生此错误信息了。
一个最佳的配置例子:(经过本人验证,自从用此配置之后,再未出现过tomcat死掉的情况)
set JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m
在linux下 在tomcathome/conf/catalina.sh中加上如标红所示的一句代码:可以增加tomcat jvm 的内存,这样就不容易出现内存溢出的现象了!
# ----- Execute The Requested Command -----------------------------------------
JAVA_OPTS="-server -Xms512m -Xmx2048m -XX:PermSize=128m -XX:MaxNewSize=256m -XX:MaxPermSize=256m"
# Bugzilla 37848: only output this if we have a TTY
2、java.lang.OutOfMemoryError: Javaheap space
第一种情况是个补充,主要存在问题就是出现在这个情况中。其默认空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。如果内存剩余不到40%,JVM就会增大堆到Xmx设置的值,内存剩余超过70%,JVM就会减小堆到Xms设置的值。所以服务器的Xmx和Xms设置一般应该设置相同避免每次GC后都要调整虚拟机堆的大小。假设物理内存无限大,那么JVM内存的最大值跟操作系统有关,一般32位机是1.5g到3g之间,而64位的就不会有限制了。
注意:如果Xms超过了Xmx值,或者堆最大值和非堆最大值的总和超过了物理内存或者操作系统的最大限制都会引起服务器启动不起来。
垃圾回收GC的角色
JVM调用GC的频度还是很高的,主要两种情况下进行垃圾回收:
当应用程序线程空闲;另一个是java内存堆不足时,会不断调用GC,若连续回收都解决不了内存堆不足的问题时,就会报out of memory错误。因为这个异常根据系统运行环境决定,所以无法预期它何时出现。
根据GC的机制,程序的运行会引起系统运行环境的变化,增加GC的触发机会。
为了避免这些问题,程序的设计和编写就应避免垃圾对象的内存占用和GC的开销。显示调用System.GC()只能建议JVM需要在内存中对垃圾对象进行回收,但不是必须马上回收,
一个是并不能解决内存资源耗空的局面,另外也会增加GC的消耗。
二、JVM内存区域组成
简单的说java中的堆和栈
java把内存分两种:一种是栈内存,另一种是堆内存
1、在函数中定义的基本类型变量和对象的引用变量都在函数的栈内存中分配;
2、堆内存用来存放由new创建的对象和数组
在函数(代码块)中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的内存空间;在堆中分配的内存由java虚拟机的自动垃圾回收器来管理
堆的优势是可以动态分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的。缺点就是要在运行时动态分配内存,存取速度较慢;
栈的优势是存取速度比堆要快,缺点是存在栈中的数据大小与生存期必须是确定的无灵活性。
java堆分为三个区:New、Old和Permanent
GC有两个线程:
新创建的对象被分配到New区,当该区被填满时会被GC辅助线程移到Old区,当Old区也填满了会触发GC主线程遍历堆内存里的所有对象。Old区的大小等于Xmx减去-Xmn
java栈存放
栈调整:参数有+UseDefaultStackSize -Xss256K,表示每个线程可申请256k的栈空间
每个线程都有他自己的Stack
三、JVM如何设置虚拟内存
提示:在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。
提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。
提示:JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。
默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。
提示:假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。
简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,
这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了
提示:注意:如果Xms超过了Xmx值,或者堆最大值和非堆最大值的总和超过了物理内存或者操作系统的最大限制都会引起服务器启动不起来。
提示:设置NewSize、MaxNewSize相等,"new"的大小最好不要大于"old"的一半,原因是old区如果不够大会频繁的触发"主" GC ,大大降低了性能
JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;
由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。
解决方法:手动设置Heap size
修改TOMCAT_HOME/bin/catalina.bat
在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:
JAVA_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m"
四、性能检查工具使用
定位内存泄漏:
JProfiler工具主要用于检查和跟踪系统(限于Java开发的)的性能。JProfiler可以通过时时的监控系统的内存使用情况,随时监视垃圾回收,线程运行状况等手段,从而很好的监视JVM运行情况及其性能。
1. 应用服务器内存长期不合理占用,内存经常处于高位占用,很难回收到低位。
相关推荐
### Eclipse Memory Analyzer (MAT) 分析 Tomcat 内存溢出详解 #### 一、引言 在软件开发过程中,特别是在 Java 应用程序中,内存管理是非常关键的一环。当应用程序遭遇 `OutOfMemoryError` 异常时,通常意味着...
### Eclipse + Tomcat 内存溢出参数设置详解 在Java开发过程中,特别是在使用Eclipse作为集成开发环境(IDE)并结合Apache Tomcat服务器进行Web应用开发时,经常会遇到内存溢出的问题。这类问题通常表现为应用程序...
### Tomcat内存溢出在不同系统上的解决方案 #### 一、引言 在部署和运维基于Java的应用程序时,Tomcat作为广泛使用的轻量级Web容器之一,常常会在高负载或资源管理不当的情况下遭遇内存溢出的问题。内存溢出不仅会...
### Tomcat内存溢出问题详解 #### 一、引言 在Java Web应用服务器领域,Apache Tomcat是一款非常流行的开源Web容器,它以其轻量级、高性能和稳定性著称。然而,在实际部署与运行过程中,Tomcat服务器可能会遇到...
### Tomcat与Eclipse配置内存溢出解决方案 #### 背景介绍 在进行Web应用程序开发过程中,尤其是在使用Tomcat服务器结合Eclipse或MyEclipse等集成开发环境(IDE)时,开发者可能会遇到一个常见的问题——内存溢出。...
### Tomcat内存优化详解 #### 一、引言 在Java Web应用开发中,Apache Tomcat作为一款轻量级的应用服务器被广泛使用。然而,在实际部署和运行过程中,经常会遇到性能瓶颈,其中最常见的问题之一就是内存溢出异常,...
#### Tomcat内存配置详解 **1. Linux环境配置** - 在`catalina.sh`文件顶部添加以下配置: ```sh JAVA_OPTS="-server –Xms1024m –Xmx2048m -XX:PermSize=128M -XX:MaxPermSize=512m -XX:-UseGCOverheadLimit" ...
解决Apache服务器或类似应用服务器如Tomcat的内存溢出问题,关键是正确理解问题的根本原因并采取适当的措施进行调整。通过合理设置JVM参数,不仅可以解决内存溢出问题,还可以提高系统的稳定性和性能。此外,对于...
### Eclipse 内存溢出解决办法详解 #### 一、PermGen Space 概念与问题成因 在Java虚拟机(JVM)中,PermGen Space(Permanent Generation Space)是专门用于存储Class和Meta信息的一个区域。当一个Class被加载到...
### Tomcat内存参数详解 在描述中提到的`catalina.sh`脚本中的`JAVA_OPTS`变量,是用于定义Java虚拟机(JVM)启动时的参数。这些参数直接影响到Tomcat服务器的性能和稳定性。以下是对几个关键参数的解析: 1. **-...
假设我们正在使用Tomcat v7.0部署一个Web应用,并遇到了内存溢出的问题。我们可以按照以下步骤解决: 1. **分析问题**: - 使用JConsole监控应用的内存使用情况。 - 查看日志文件,确认是否是特定操作导致内存...
### 为Tomcat设置内存详解 #### 一、引言 在使用Tomcat服务器部署Java Web应用时,可能会遇到一个常见的问题:内存溢出错误。这种情况通常发生在服务器资源不足或应用消耗内存过大时。为了解决这个问题,我们需要...
#### 二、PermGen 空间溢出详解 ##### 2.1 PermGen 概念解析 PermGen 全称为 Permanent Generation space,是 JVM 的一部分,用于存储 Class 文件的元数据信息。每当加载一个类时,其元数据(如类定义、静态变量等...
### JVM内存区域详解 了解JVM的内存布局有助于更好地理解内存泄漏等问题的发生原因。 - **Heap区**:堆是JVM管理的最大内存区域,用于存储所有Java对象实例。它可以进一步细分为: - **Eden Space**:新创建的...
### Java虚拟机(JVM)内存设置与调优详解 #### 引言 在现代软件开发中,Java虚拟机(JVM)作为执行Java字节码的核心组件,其性能直接影响到Java应用的运行效率与稳定性。特别是在大数据处理场景下,合理设置JVM内存...
- **内存溢出问题**:调整JVM的堆大小参数(Xms、Xmx),避免因内存不足导致的应用崩溃。 #### 六、总结 通过上述步骤,我们可以成功地在myEclipse6.5环境中集成Tomcat7,并解决了常见的启动错误问题。这对于进行...
#### 二、Java内存溢出详解 Java内存溢出问题通常发生在JVM的内存管理出现问题时。主要有三种常见的类型: 1. **JVM Heap(堆)溢出**: - **常见原因**:当应用程序创建的对象过多,导致JVM的Heap空间不足时,就...