一、 HotSpot堆内存结构
现在JVM基本上都是HotSpot。接下来先看看堆内存的结构
HotSpot将堆内存分成上面三部分,分别是:新生代(Young Generation)、老年代(Old Generation)、持久代(Permanent Generation)。先大体说下这三部分的作用,然后循序渐进进行深入,学习知识也是要迭代多次,才能更好的理解,一口吃不了一个大胖子,这是题外话了。
新生代(Young Generation)
新创建的类绝大部分都被分配到这个区域。由于大部分对象创建后很快会不可达到,所以绝大部分对象在新生代创建,然后很快销毁。对象从新生代销毁的过程叫Minor GC。(翻译一下:小型的垃圾回收
与老年代、持久代不同的是,新生代又被分为三个部分,即上图的Eden,S0,S1。先记住新生代的这三个子部分,下文具体说明。
老年代(Old Generation)
从新生代对象没有不可达,并且存活下来,会被拷贝到这个区域。这个区域所占的空间比新生代的大,也正是因为这个空间比较大,所以GC的频率比新生代少很多。对象从老年代销毁的过程叫Major GC。(翻译一下:大型的垃圾回收)
持久代(Permanent Generation)
本人很喜欢这个区域,因为他够持久!男人就要持久。。。
这个区域也被叫做方法区,存放字节码等文件,常量池也是位于这区域。这个区域如果达到阈值会触发Full GC。Full GC 会清理新生代,老年代以及持久代三个区域。
总结:为什么堆区域会分新生代和老年代?对于大部分应用,常驻对象不多。因为大部分存活寿命不长,新生代和老年代的划分有利于区分对待和缩小垃圾回收范围。(Most allocated objects are not referenced (considered live) for long, that is, they die young. Few references from older to younger objects exist.)
二、HotSpot内存回收策略
GC(垃圾回收)的一般思路是标记live objects →是否压缩→清理→压缩。
新生代GC(YouGC)
Minor GC作用于新生代,从上文可知新生代分为Eden ,S0,S1三个区域,Eden用于生成新的对象,另外两部分是救助区(Survivor Space),这两部分总是转换From、To的角色。先扫描Eden,把存活的对象复制到To,如果To放不下的对象直接拷贝到老年代;再从From区扫描存活的对象,如果达到存活次数的阈值就移动到老年代,剩下的拷贝到To区。这一套完成后From和To的角色互换,维持活动对象在救助区的不断复制,直到它们进入OldGen。(From和To对应上面的S0和S1)
老年代GC(OldGC)
Major GC作用于老年代,相比新生代的YouGC频率很高,Major GC的执行的频率很少。识别过程大致是:识别存活的对象,识别垃圾并回收,然后滑动对象并压缩对象到持续的空间。
总结如下
三、四种内存泄露
- 栈溢出(StackOverflowError)
- 堆溢出(OutOfMemoryError:java heap space)
- 持久代溢出(OutOfMemoryError: PermGen space)
- OutOfMemoryError:unable to create native thread
栈溢出StackOverflowError:出现这种错误一般是由于程序问题引起的,比如死递归等。我们知道在函数中基本变量和对象的引用都是在栈内存中分配。当在函数中定义了一个变量时,栈内存会给这个变量分配内存。当超过变量的作用域后,GC将会释放为该变量分配的内存空间。但是如果死递归一直不会结束,并且每一次递归生成的局部变量都不会释放,因为函数还在执行。最终栈不可访问,抛出StackOverflowError.
堆溢出OutOfMemoryError:java heap space: 堆内存溢出会抛出OOME,出现这种问题有可能是内存泄露,也可能是内存溢出。这两种情况比较麻烦,我还在研究阶段。先挖个坑,研究明白了补上。
持久代溢出(OutOfMemoryError: PermGen space):HotSpot jvm通过持久代实现了java虚拟机规范的方法区,这个区域存放的是class对象、程序运行时的常量池。所以OutOfMemoryError:PermGen space有可能是常量池溢出,也有可能是class对象没有及时释放而引起的溢出。常见的有以下几种情况:
1.我们平时修改好代码并保存,tomcat会进行热部署。这时候很可能抛出OutOfMemoryError: PermGen space。这是因为原来的class对象没有卸载掉,新的class对象加入方法区,达到方法区的阈值后抛出异常。
2如果应用程序本身比较大,涉及的类库比较多,但是我们分配给持久带的内存(通过-XX:PermSize和-XX:MaxPermSize来设置)比较小的时候也可能出现此种问题。
3.class动态生成技术,比如CGLib动态代理等,这种情况下需要更大的方法区空间来存储动态生成的class对象。
OutOfMemoryError:unable to create native thread:字面意思是内存溢出:无法创建新的线程。字面意思已经很明显了,出现这种情况的原因基本下面2点
1.程序创建的线程数超过操作系统的限制。
2.JVM占用的内存太多,导致创建线程的内存空间太小。我们都知道操作系统对每个进程的内存是有限制的,我们启动Jvm,相当于启动了一个进程,假如我们一个进程占用了4G的内存,那么通过下面的公式计算出来的剩余内存就是建立线程栈的时候可以用的内存。 线程栈总可用内存=4G-(-Xmx的值)- (-XX:MaxPermSize的值)- 程序计数器占用的内存
通过上面的公式我们可以看出,-Xmx 和 MaxPermSize的值越大,那么留给线程栈可用的空间就越小,在-Xss参数配置的栈容量不变的情况下,可以创建的线程数也就越小。因此如果是因为这种情况导致的unable to create native thread
,那么要么我们增大进程所占用的总内存,或者减少-Xmx或者-Xss来达到创建更多线程的目的。
相关推荐
JVM 内存溢出问题解析 JVM 内存溢出是指程序运行所需的内存大于虚拟机能提供的最大内存的情况。这种情况可能是由于数据量过大、死循环、静态变量和静态方法过多、递归、无法确定是否被引用的对象等原因引起的。同时...
**JVM内存溢出**是一种常见的运行时错误,指的是程序在执行过程中因为无法获得足够的内存资源而导致的问题。这种问题通常发生在程序尝试分配超出系统可用内存限制的新对象时。了解JVM内存结构是理解内存溢出的关键。...
理解JVM内存结构和内存分配机制对于避免内存溢出(OutOfMemoryError)、提升程序性能、减少垃圾回收开销至关重要。开发者应关注内存配置、对象生命周期管理以及适当的垃圾回收策略,以优化应用程序的性能和稳定性。
简单的判断JVM内存溢出的方法
MAT,全称Memory Analyzer Tool,是IBM开发的一款强大的JVM内存分析工具,尤其适用于诊断Java应用程序的内存泄漏问题。在Java开发过程中,内存溢出(Out Of Memory)问题常常会导致程序异常终止,而MAT就是解决这类...
JVM内存模型是Java虚拟机(JVM)中的一种内存管理机制,它将内存区分为永久区内存(Permanent space)和堆内存(heap space)两大块。永久区内存用于存放加载的Class类级对象,如class本身、method、field等等,而堆...
首先,我们来分析Tomcat内存溢出的三种典型情况: 1. **OutOfMemoryError: Java heap space**:这是由于Java堆内存不足造成的。Java堆主要存储对象实例,如果分配的堆空间不足以创建新的对象,就会抛出这个错误。...
给定的部分内容中提到了一些JVM的启动参数,这些参数直接关联到内存溢出配置,下面我们来逐一解析: - **-Xms1024m**:设置JVM初始分配的堆内存大小为1024MB。这意味着JVM启动时,会立即申请1024MB的物理内存。 - *...
本文主要讨论了 JVM 中的内存溢出问题,包括内存溢出的定义、内存泄漏和内存溢出的区别与联系、JVM 垃圾回收机制、内存溢出的原因分析、常见的四种内存溢出情况以及解决方案。 一、内存溢出的定义 内存溢出是指...
本文将深入探讨如何在Java中获取JVM内存大小,包括堆内存的总量、最大值以及剩余空间,并解析给定代码片段中的关键概念。 ### JVM内存模型 在讨论如何获取JVM内存大小之前,首先需要理解JVM的内存布局。JVM内存...
JVM内存模型与垃圾回收是...总的来说,理解JVM内存模型和垃圾回收机制对于优化Java应用性能至关重要,它涉及到内存分配策略、垃圾收集算法的选择以及内存参数的调整,这些都需要开发者具备深入的JVM知识和实践经验。
在实际开发过程中,可能会遇到以下几种内存溢出异常: 1. **`java.lang.OutOfMemoryError: Java heap space`**:这表示堆内存已满。通常,这可能是由于项目中引用了大量的jar包或其他资源导致内存使用超出预期。...
### JVM实战-对象访问与内存溢出异常解析 #### 实验背景与目标 在Java虚拟机(JVM)中,不同的内存区域负责不同的功能,并且各自可能会出现特定类型的内存溢出异常。通过本实验,旨在深入理解JVM内存管理机制以及...
综上所述,解决此类问题需要综合运用JVM内存模型知识、代码分析技巧以及使用专业工具进行诊断。通过以上步骤,开发者可以定位内存溢出的根本原因,从而优化代码和调整JVM配置,防止类似问题再次发生。
标题中的“关于tomcat乱码以及tomcat jvm 内存溢出问题的解决方案和理论”涉及了两个关键的IT概念:Tomcat服务器的字符编码问题和Java虚拟机(JVM)内存管理的问题。让我们逐一深入探讨这两个主题。 首先,我们来...
本文将详细解析JVM的内存结构、内存分配策略以及相关的配置参数。 1. **JVM内存结构** JVM内存主要分为以下几个区域: - **方法区(Method Area)**:这是所有线程共享的区域,存储类信息、常量、静态变量、...
tomcat修改JVM内存配置(解决大项目内存溢出问题有效方案)
【ha456.jar(IBMHeapAnalyzer)JVM内存分析工具】是一款由IBM开发的专业工具,主要用于诊断Java虚拟机(JVM)的内存问题。它能够解析和分析JVM生成的内存转储文件(通常称为heap dump或hprof文件),帮助开发者识别...
### JVM内存管理详解 #### 一、引言 在探讨JVM内存管理之前,我们先来看一下为何要深入了解这一主题。对于深入掌握Java的人来说,内存管理是不可或缺的一部分。随着技术的发展,内存管理变得越来越自动化,但这也...