JVM内存机制资料笔记
- 格式:doc
- 大小:88.50 KB
- 文档页数:6
JVM的内存管理机制详解JVM是Java虚拟机的缩写,它是Java程序的运行环境。
JVM的内存管理机制是其核心功能之一,它负责管理Java程序的内存分配和回收,包括对象的创建、使用和销毁等。
JVM的内存管理机制主要由堆、栈和方法区组成。
堆是Java程序运行时的动态数据区,用来存储对象实例和数组。
栈是每个线程私有的,用来存储局部变量、方法参数和运算数据等。
方法区是存储类信息、常量、静态变量和编译器优化后的代码等。
堆是Java程序最大的内存区域,被所有线程共享。
在JVM启动时,会预设一个初始大小,但它可以动态地扩展或收缩。
堆内存由年轻代和老年代组成。
年轻代分为Eden区和两个Survivor区(名为S0和S1)。
当新对象被创建时,它们会被放在Eden区。
当Eden区满时,会触发垃圾回收,把不再被引用的对象回收掉,而仍然存活的对象会被移动到Survivor区。
经过多次垃圾回收后仍然存活的对象会被移动到老年代。
老年代中的对象会比较稳定,一般不会被频繁回收。
栈是线程私有的,用于存储局部变量、方法参数和运算数据等。
栈的大小是固定的,由编译器预先确定,并在线程创建时分配。
每个栈帧由局部变量表、操作数栈、动态链接和方法出口等组成。
当方法被调用时,JVM会为该方法创建一个栈帧,当方法返回时,栈帧就会被销毁。
栈帧的销毁顺序和创建顺序相反,即最后创建的栈帧最先销毁。
方法区是线程共享的,用于存储类信息、常量、静态变量和编译器优化后的代码等。
方法区大小是固定的,通常比堆小。
在方法区中,类的信息会一直保存,直到JVM退出。
方法区还包括运行时常量池,用来存储编译期生成的字面量和符号引用。
符号引用是对类、字段和方法的符号引用,如类或方法的全限定名。
字面量是Java程序中的常量,如字符串、整数和浮点数等。
在JVM中,内存的分配和回收是通过垃圾回收器(GC)来完成的。
GC会定期地检查堆中的对象,将不再被引用的对象回收掉,释放内存空间。
JVM的内存机制介绍JVM(Java Virtual Machine)是Java虚拟机的缩写,是一种用于执行Java字节码的虚拟计算机。
JVM的内存机制包括堆内存、栈内存、方法区、本地方法栈和程序计数器等几个部分。
下面,我将对每个部分的内存机制进行详细介绍。
1. 堆内存(Heap Memory):堆内存是JVM中最大的一块内存区域,用于存储对象实例。
Java中所有的对象都在堆内存中进行分配和回收。
堆内存分为两个区域:新生代和老年代。
新生代又分为Eden区、From Survivor区和To Survivor区。
- Eden区是对象被创建时的初始分配区域,大部分对象首先在Eden区进行分配。
- Survivor区是用于存放幸存的对象的区域,当Eden区满了后,一部分幸存的对象会被移动到Survivor区中。
- 当Survivor区满了,对象会被移到老年代中。
堆内存的大小可以通过启动参数或命令行选项进行调整。
2. 栈内存(Stack Memory):栈内存用于存储局部变量、方法参数、对象的引用和方法调用的记录等。
每个线程都有一个独立的栈内存空间,栈中的数据是线程私有的,线程之间不能共享。
栈内存的大小由系统决定,不需要手动调整。
每个方法被调用时,JVM会自动创建一个栈帧(Stack Frame),用于存储方法的信息和临时变量等。
当方法执行完成后,栈帧被销毁,释放内存空间。
3. 方法区(Method Area):方法区是用于存储类的结构信息、方法和常量池等。
它是所有线程共享的区域,用于存储编译后的类信息、静态变量、常量和字节码等。
方法区的大小也由系统决定,不需要手动调整。
方法区的内存空间可以进行垃圾回收,但通常情况下,垃圾回收只会清理无用的类和常量等。
4. 本地方法栈(Native Method Stack):本地方法栈用于执行本地方法(Native Method)的数据区域。
本地方法是指使用其他语言(如C、C++)编写的方法,通过本地方法接口(JNI)与Java代码进行交互。
JVM内存分配机制及类加载过程概述JVM(Java虚拟机)内存分配机制分为以下三个部分:
1.静态存储区(方法区):这部分内存内存在程序编译时就已经分配好,并
且在整个程序运行期间都一直存在。
主要存放静态数据,如全局static数据和常量。
2.栈区:栈内存主要存储函数(方法)中定义的基本类型变量和对象的引用
变量。
当方法执行时,方法内的局部变量都在栈内存中创建,并在方法执行结束后自动释放。
此外,JVM中的栈内存是连续的内存区域,其大小由系统决定。
3.堆区:堆区用于动态内存分配,例如通过new来申请任意大小的内存(对
象或数组)。
堆区不连续,并且需要程序员手动释放。
其内存管理依赖于垃圾回收机制。
此外,JVM在遇到new指令时,会检查该指令的参数是否能在常量池中找到一个类的符号引用,并检查这个符号引用指向的类是否被加载、解析和初始化过。
如果未完成这些步骤,则会执行类加载过程。
在类加载完成后,JVM会为新生的对象分配内存,并初始化这些内存区域。
以上信息仅供参考,如需更多信息,建议咨询专业技术人员或查阅相关书籍文献。
JVM学习笔记Java内存模型一Java内存模型1、运行时数据区域1.1 程序计数器程序计数器(Program Counter Register)是一块较小的内存空间,可以看成是当前线程所执行的字节码的行号指示器。
字节码解释器工作时就是通过改变这个计数器的值来选取吓一跳需要执行的字节码指令。
线程私有,每条线程都需要有一个独立的程序计数器,各条线程之间互不影响,独立存储。
如果线程正在执行一个Java Method,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的Native Method,这个计数器的值为空(Undefined)。
此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError的区域。
1.2 Java虚拟机栈Java虚拟机栈(Java Virtual Machine Stacks)线程私有,生命周期与线程相同。
虚拟机栈描述的Java方法执行的内存模型: 每个方法在执行的同时,都会创建一个栈帧(Stack Frame),用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
每个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
局部变量表存放了编译期可知的各种基本数据类型(boolean, byte, char, short, int, float, long ,double), 对象引用(reference类型,它不等同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是一个代表对象的句柄或其他与此对象相关的位置)和returnAddress类型(指向了一条字节码指令的地址)其中64位长度的long,double类型的数据会占用2个局部变量空间(slot),其余的数据类型只占用1 个。
局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,这个方法在运行期间不会改变局部变量表的大小。
JVM的内存机制介绍JVM(Java Virtual Machine)是Java程序的运行环境,它负责解释和执行Java字节码,以及管理Java程序的内存使用。
JVM的内存机制包括堆内存和非堆内存,其中堆内存又分为新生代和老年代。
本文将详细介绍JVM的内存机制。
1.堆内存堆内存是Java程序运行时存储对象实例的地方。
在JVM启动时,就会分配一个固定大小的堆内存空间。
堆内存又分为新生代和老年代。
1.1新生代新生代是新创建的对象的存储区域,通常用于存放生命周期较短的对象。
它又分为Eden空间、Survivor0空间和Survivor1空间。
- Eden空间:是对象最初被创建的地方。
当Eden空间不够存放新创建的对象时,触发Minor GC(年轻代垃圾收集器)对Eden空间进行垃圾回收,将仍然存活的对象复制到Survivor0或Survivor1空间中。
- Survivor0和Survivor1空间:是存放经过一次Minor GC后仍然存活的对象的地方。
当Survivor空间不够存放存活对象时,触发Minor GC,将仍然存活的对象复制到另一个Survivor空间中,同时对原空间进行垃圾回收。
1.2老年代老年代是存放长时间存活的对象的地方,通常存放生命周期较长的对象。
当一个对象经过多次Minor GC后仍然存活,就会被晋升到老年代中。
老年代的垃圾回收称为Major GC(Full GC),它会对整个堆空间进行垃圾回收。
2.非堆内存非堆内存是用来存放程序数据和JVM自身数据的地方,它不是由Java虚拟机管理的内存区域。
在Java8及之前的版本中,非堆内存主要包括方法区和本地方法栈。
2.1方法区方法区用于存放类的结构信息,包括类、方法、字段、静态变量等。
方法区的大小是固定的,通过设置JVM参数进行配置。
在方法区中,通过不同的垃圾回收算法对被废弃的类进行垃圾回收。
2.2本地方法栈本地方法栈用于执行本地方法(即非Java语言编写的方法,例如C/C++),它提供了Java和本地方法之间的接口。
JVM内存机制-笔记内存管理来源:在程序运行过程当中,会创建大量的对象,这些对象,大部分是短周期的对象,小部分是长周期的对象,对于短周期的对象,需要频繁地进行垃圾回收以保证无用对象尽早被释放掉,对于长周期对象,则不需要频率垃圾回收以确保无谓地垃圾扫描检测。
为解决这种矛盾,Sun JVM的内存管理采用分代的策略。
Sun JVM有4垃圾回收器:∙Serial Collector[默认]:序列垃圾回收器,垃圾回收器对Young Gen和Tenured Gen都是使用单线的垃圾回收方式,对Young Gen,会使用拷贝策略避免内存碎片,对Old Gen,会使用压缩策略避免内存碎片。
基本上,在对内核的服务器上应该避免使用这种方式。
在JVM启动参数中使用-XX:+UseSerialGC启用Serial Collector。
∙Parallel Collector:并发垃圾回收器,垃圾回收器对Young Gen和Tenured Gen都是使用多线程并行垃圾回收的方式,对Young Gen,会使用拷贝策略避免内存碎片,对Old Gen,会使用压缩策略避免内存碎片。
在JVM启动参数中使用-XX:+UseParallelGC启用Parallel Collector。
∙Parallel Compacting Collector:并行压缩垃圾回收器,与Parallel Collector垃圾回收类似,但对Tenured Gen会使用一种更有效的垃圾回收策略,此垃圾回收器在暂停时间上会更短。
在JVM启动参数中使用-XX:+UseParallelOldGC启用ParallelCompacting Collector。
∙Concurrent Mark-Sweep (CMS) Collector:并发标志清除垃圾回收器,对Young Gen会使用与Parallel Collector同样的垃圾回收策略,对Tenured Gen,垃圾回收的垃圾标志线程与应用线程同时进行,而垃圾清除则需要暂停应用线程,但暂停时间会大大缩减,需要注意的是,由于垃圾回收过程更加复杂,会降低总体的吞吐量。
Jvm工作原理学习笔记一、JVM的生命周期1.JVM实例对应了一个独立运行的java程序它是进程级别a)启动。
启动一个Java程序时,一个JVM实例就产生了,任何一个拥有public static voidmain(String[] args)函数的class都可以作为JVM实例运行的起点b)运行。
main()作为该程序初始线程的起点,任何其他线程均由该线程启动。
JVM内部有两种线程:守护线程和非守护线程,main()属于非守护线程,守护线程通常由JVM自己使用,java程序也可以标明自己创建的线程是守护线程c)消亡。
当程序中的所有非守护线程都终止时,JVM才退出;若安全管理器允许,程序也可以使用Runtime类或者System.exit()来退出2.JVM执行引擎实例则对应了属于用户运行程序的线程它是线程级别的二、JVM的体系结构1.类装载器(ClassLoader)(用来装载.class文件)2.执行引擎(执行字节码,或者执行本地方法)3.运行时数据区(方法区、堆、java栈、PC寄存器、本地方法栈)三、JVM类加载器JVM整个类加载过程的步骤:1.装载装载过程负责找到二进制字节码并加载至JVM中,JVM通过类名、类所在的包名通过ClassLoader来完成类的加载,同样,也采用以上三个元素来标识一个被加载了的类:类名+ 包名+ClassLoader实例ID。
2.链接链接过程负责对二进制字节码的格式进行校验、初始化装载类中的静态变量以及解析类中调用的接口、类。
完成校验后,JVM初始化类中的静态变量,并将其值赋为默认值。
最后对类中的所有属性、方法进行验证,以确保其需要调用的属性、方法存在,以及具备应的权限(例如public、private域权限等),会造成NoSuchMethodError、NoSuchFieldError 等错误信息。
3.初始化初始化过程即为执行类中的静态初始化代码、构造器代码以及静态属性的初始化,在四种情况下初始化过程会被触发执行:调用了new;反射调用了类中的方法;子类调用了初始化;JVM启动过程中指定的初始化类。
jvm内存管理机制Java虚拟机(JVM)是一种用于Java程序执行的虚拟机。
JVM内存管理机制是确保Java程序顺利执行的重要基础。
在本文中,我们将通过以下步骤详细介绍JVM内存管理机制。
第一步:JVM内存模型JVM内存模型是JVM用于管理内存的核心。
JVM内存模型可分为线程栈、堆以及方法区(也称为永久区)。
线程栈用于存储线程执行时的栈帧,每个栈帧包含方法调用信息、局部变量以及操作数栈。
堆是Java程序中所有对象的存储区域,其中包括数组以及对象。
方法区用于存储类的信息、方法信息以及静态变量。
第二步:JVM内存分配JVM内存分配可分为对象分配、栈帧分配以及类信息分配。
对象分配是在堆中分配内存以存储对象的过程。
栈帧分配是在每个线程栈中分配内存以存储栈帧的过程。
类信息分配是在方法区中分配内存以存储类信息、方法信息以及静态变量。
第三步:JVM内存回收JVM内存回收是确保Java程序获得足够内存的重要机制。
JVM内置垃圾回收器用于回收无用对象占用的内存。
JVM垃圾回收器可分为串行垃圾回收器、并行垃圾回收器以及CMS垃圾回收器。
串行垃圾回收器是一种单线程回收器,用于小型应用程序;并行垃圾回收器是一种多线程回收器,用于大型应用程序;CMS垃圾回收器是一种以最小停顿时间为目标的垃圾回收器,用于大型应用程序。
第四步:JVM性能调优JVM内存管理机制对Java程序的性能有着至关重要的影响。
JVM 性能调优是确保Java程序最佳性能的重要手段。
JVM性能调优可分为如下几个方面:1. 内存设置:内存设置决定了JVM所使用的最大内存以及初始内存大小。
2. GC设置:GC设置包括选择合适的垃圾回收器以及调整垃圾回收器参数。
3. 线程设置:线程设置包括调整线程池大小以及线程优先级等。
4. 类加载设置:类加载设置包括调整类加载路径以加快类加载速度。
5. 程序代码优化:程序代码优化可通过使用缓存、避免重复计算以及使用合适的算法等手段来提高程序性能。
JVM 内存管理和GC知识概述和总结JVM 内存结构程序计数器java虚拟机栈本地方法栈:本地方法栈则为使用到的本地操作系统(Native)方法服务方法区java堆区线程共享:方法区和java堆区操作系统中的内存分配主要包括:静态内存分配、栈内存分配、堆内存分配JVM 栈内存分配和堆内存分配栈内存分配java栈空间的分配是和线程绑定在一起的,当一个线程创建时,JVM 就会为这个线程创建一个新的Java栈,一个线程的方法的调用和返回对应这个Java栈的压栈和出栈。
当线程激活一个Java方法时,JVM 就会在线程的Java栈里新压入一个栈桢。
用来保存参数、局部变量、中间计算过程和其他数据。
退出方法的时候,修改栈顶指针就可以把栈帧中的内容销毁。
3.堆内存分配每一个Java应用都唯一对应一个JVM实例,每一个实例又对应一个堆。
Java 应用程序在运行中所创建的几乎所有的类实例或数组都会放在这个堆中(随着JIT编译器的发展和逃逸分析技术的逐渐成熟,栈上分配、标量替换让一些对象直接在栈上进行分配,从而提升程序性能),并由该应用程序的所有线程所共享。
Java中分配堆空间时在启动时自动初始化的,对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码显示地释放,由垃圾回收机制负责回收这些内容区域。
内存分配与回收就Java语言而言,内存分配主要包括静态内存分配和动态内存分配。
∙静态内存分配是指在Java被编译时就已经确定了所需的内存空间,当程序被加载时系统把内存一次性分配给它,在程序执行时不发生变化,程序执行结束时内存被回收。
例如:程序计数器、虚拟机栈、本地方法栈3个区域随着线程而生,随线程而灭;栈中的栈帧随着方法的进入和退出不停的进栈和出栈。
这几个区域的分配分配和回收都具有确定性,无需过多考虑。
栈帧中存储了方法的局部变量表、操作数栈、动态链接和方法返回地址等信息。
jvm精讲笔记JVM(Java Virtual Machine),那可真是Java世界里的超级大明星呢。
咱今儿就好好唠唠关于JVM的那些事儿。
一、啥是JVM。
JVM啊,就像是Java程序的一个超级大管家。
Java程序想要跑起来,全得靠它呢。
它就像是一个虚拟的小世界,专门给Java代码提供运行的环境。
你想啊,咱们写的Java代码,如果没有JVM,就像小树苗没有土壤一样,根本没法生长。
而且这个JVM还很神奇,它能让Java实现“一次编写,到处运行”的梦想。
不管是在Windows 系统上,还是在Linux或者Mac系统上,只要有对应的JVM,Java程序就能欢快地跑起来。
这就好比是一个万能钥匙,能打开各种系统的大门。
二、JVM的体系结构。
1. 类加载器(ClassLoader)类加载器就像是一个勤劳的小搬运工。
它的任务呢,就是把咱们写好的.class文件加载到JVM里。
这里面还有不同种类的类加载器呢。
有引导类加载器(Bootstrap ClassLoader),这可是类加载器里的老大,它负责加载Java核心类库,就像一个家族里的老祖宗,管着最最重要的东西。
然后还有扩展类加载器(Extension ClassLoader),它主要负责加载Java的扩展库,就像是家族里负责拓展业务的小能手。
最后还有应用程序类加载器(Application ClassLoader),这个就是负责加载咱们自己写的那些类啦,就像是照顾自家孩子的小保姆。
这几个类加载器之间还有个很有趣的关系,就像一个层层递进的小梯队,一个管着一个呢。
2. 运行时数据区(Runtime Data Areas)这个运行时数据区可就像是JVM的大仓库,里面分成好多小房间。
- 堆(Heap)堆啊,那可是JVM里的大仓库,专门用来存放对象实例的。
就像一个超级大的储物间,Java程序里创建的那些对象,都一股脑儿地往这里面放。
不过这个堆也有自己的烦恼,因为如果对象创建得太多,就可能会出现内存不够用的情况,就像储物间堆满了东西,都快放不下啦。
JVM内存机制资料笔记参考
JDK5.0垃圾收集优化之--Don't Pause
/calvinxiu/archive/2007/05/18/1614473.aspx
JVM内存模型以及垃圾回收
/xuwanbest/blog/item/0587d82f2c44a73d1e30892e.html
对jvm内存的一些理解
/midstr/archive/2008/09/21/230292.html
了解JVM的内存管理与垃圾回收
/jiaozhenqing/blog/item/f18b85d4c1063a07a08bb77e.html
Java内存溢出的解决方案
/yanghlcn/blog/item/029e7303917b528dd43f7cc3.html
Java内存组成
堆(Heap)
运行时数据区域,所有类实例和数组的内存均从此处分配。
Java 虚拟机启动时创建。
对象的堆内存由称为垃圾回收器的自动内存管理系统回收。
组成
News Generation(Young Generation即图中的Eden + From Space + To Space)
Eden 存放新生的对象
Survivor Space 两个存放每次垃圾回收后存活的对象
Old Generation(Tenured Generation 即图中的Old Space)主要存放应用程序中生命周期长的存活对象
非堆内存
JVM具有一个由所有线程共享的方法区。
方法区属于非堆内存。
它存储每个类结构,如运行时常数池、字段和方法数据,以及方法和构造方法的代码。
它是在 Java 虚拟机启动时创建的。
除了方法区外,Java 虚拟机实现可能需要用于内部处理或优化的内存,这种内存也是非堆内存。
例如,JIT 编译器需要内存来存储从 Java 虚拟机代码转换而来的本机代码,从而获得高性能。
组成
Permanent Generation(图中的Permanent Space)存放JVM自己的反射对象,比如类对象和方法对象
native heap
GC策略
堆
JVM采用一种分代回收 (generational collection) 的策略,用较高的频率对年轻的对象(young generation)进行扫描和回收,这种叫做minor collection,而对老对象(old generation)的检查回收频率要低很多,称为major collection。
这样就不需要每次GC都将内存中所有对象都检查一遍。
当一个URL被访问时,内存申请过程如下:
A. JVM会试图为相关Java对象在Eden中初始化一块内存区域
B. 当Eden空间足够时,内存申请结束。
否则到下一步
C. JVM试图释放在Eden中所有不活跃的对象(这属于1或更高级的垃圾回收), 释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor 区
D. Survivor区被用来作为Eden及OLD的中间交换区域,当OLD区空间足够时,Survivor 区的对象会被移到Old区,否则会被保留在Survivor区
E. 当OLD区空间不够时,JVM会在OLD区进行完全的垃圾收集(0级)
F. 完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”out of memory错误”
对象衰老的过程
young generation的内存,由一块Eden(伊甸园,有意思)和两块Survivor Space(1.4文档中称为semi-space)构成。
新创建的对象的内存都分配自eden。
两块Survivor Space总有会一块是空闲的,用作copying collection的目标空间。
Minor collection 的过程就是将eden和在用survivor space中的活对象copy到空闲survivor space 中。
所谓survivor,也就是大部分对象在伊甸园出生后,根本活不过一次GC。
对象在young generation里经历了一定次数的minor collection后,年纪大了,就会被移到old generation中,称为tenuring。
(是否仅当survivor space不足的时候才会将老对象tenuring? 目前资料中没有找到描述)
剩余内存空间不足会触发GC,如eden空间不够了就要进行minor collection,old generation空间不够要进行major collection,permanent generation空间不足会引发full GC。
非堆内存
GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的应用中有很多CLASS的话,就很可能出现PermGen space错误。
JVM的默认设置
堆(heap)(News Generation 和Old Generaion 之和)的设置
初始分配的内存由-Xms指定,默认是物理内存的1/64但小于1G。
最大分配的内存由-Xmx指定,默认是物理内存的1/4但小于1G。
默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制,可以由
-XX:MinHeapFreeRatio=指定。
默认空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制,可以由
-XX:MaxHeapFreeRatio=指定。
服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小,所以上面的两个参数没啥用。
-Xmn 设置young generation的heap大小
-XX:MinHeapFreeRatio与-XX:MaxHeapFreeRatio设定空闲内存占总内存的比例范围,这两个参数会影响GC的频率和单次GC的耗时。
-XX:NewRatio决定young与old generation的比例。
Young generation空间越大,minor collection频率越低,但是
old generation空间小了,又可能导致major collection频率增加。
-XX:NewSize和-XX:MaxNewSize直接指定了young generation的缺省大小和最大大小。
非堆内存的设置
默认分配为64M
-XX:PermSize设置最小分配空间,-XX:MaxPermSize设置最大分配空间。
一般把这两个数值设为相同,以减少申请内存空间的时间。
内存溢出的原因
Old Generation溢出
这种内存溢出是最常见的情况之一,产生的原因可能是:
1) 设置的内存参数过小(ms/mx, NewSize/MaxNewSize)
解决方法:
1G内存环境下java jvm 的参数设置参考:
-server -Xms800m -Xmx800m -XX:PermSize=64M -XX:MaxNewSize=256m
-XX:MaxPermSize=128m -Djava.awt.headless=true
2) 程序问题
单个程序持续进行消耗内存的处理,如循环几千次的字符串处理,对字符串处理应建议使用StringBuffer。
此时不会报内存溢出错,却会使系统持续垃圾收集,无法处理其它请求,相关问题程序可通过Thread Dump获取。
单个程序所申请内存过大,有的程序会申请几十乃至几百兆内存,此时JVM也会因无法申请到资源而出现内存溢出,对此首先要找到相关功能,然后交予程序员修改,要找到相关程序,必须在Apache日志中寻找。
当Java对象使用完毕后,其所引用的对象却没有销毁,使得JVM认为他还是活跃的对象而不进行回收,这样累计占用了大量内存而无法释放。
由于目前市面上还没有对系统影响小的内存分析工具,故此时只能和程序员一起定位。
Permanent Generation 溢出
通常由于 Perm 段装载了大量的类而导致溢出,如 spring的动态生成类。
目前的解决办法:
1) 将 Perm Size扩大,一般256M能够满足要求
2) 若别无选择,则只能将servlet的路径加到CLASSPATH中,但一般不建议这么处理
C Heap溢出
系统对C Heap没有限制,故C Heap发生问题时,Java进程所占内存会持续增长,直到占用所有可用系统内存。