JVM之垃圾回收遇到的问题
怎么判断对象可以被回收
根搜索算法
在主流的商用程序语言中(java和c#),都是使用根搜索算法(GC Roots Tracing)判断对象是否存活的。这个算法的基本思路就是通过一系列的名为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连(用图论的话来说就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。
java中可以作为GC Root的对象
- 虚拟机栈(栈帧中的本地变量表)中的引用对象
- 方法区中的类静态属性引用的对象
- 方法区中的常量引用的对象
- 本地方法栈中JNI(即Native方法)的引用的对象
如何处理内存碎片
- 将标记-清除算法改为复制、标记-整理算法
- 在标记-清除算法执行完后,执行一次内存整理
如何解决同时存在的对象创建和对象回收问题
垃圾回收线程是回收内存的,而程序运行线程则是消耗(或分配)内存的,一个回收内存,一个分配内存,从这点看,两者是矛盾的。
解决方法一
在现有的垃圾回收方式中,要进行垃圾回收前,一般都需要暂停整个应用(即:暂停内存的分配),然后进行垃圾回收,回收完成后再继续应用。这种实现方式是最直接,而且最有效的解决二者矛盾的方式。
缺点:当堆空间持续增大时,垃圾回收的时间也将会相应的持续增大,对应应用暂停的时间也会相应的增大。一些对相应时间要求很高的应用,比如最大暂停时间要求是几百毫秒,那么当堆空间大于几个G时,就很有可能超过这个限制。
解决方法二
使用并发垃圾回收算法,使用这种算法,垃圾回收线程与程序运行线程同时运行。在这种方式下,解决了暂停的问题。
缺点:因为需要在新生成对象的同时又要回收对象,算法复杂性会大大增加,系统的处理能力也会相应降低,同时,“碎片”问题将会比较难解决。
系统崩溃前的一些现象:
- 每次垃圾回收的时间越来越长,由之前的10ms延长到50ms左右,FullGC的时间也有之前的0.5s延长到4、5s
- FullGC的次数越来越多,最频繁时隔不到1分钟就进行一次FullGC
- 年老代的内存越来越大并且每次FullGC后年老代没有内存被释放
- 之后系统会无法响应新的请求,逐渐到达OutOfMemoryError的临界值。
怎么知道服务器访问越来越慢的原因呢?
- 来几次内存快照信息,分析快照信息
- 看是不是内存溢出,导致垃圾回收时间变长,垃圾回收时间变长,就会影响程序运行
- 生成当前的Heap dump信息,大小为一个3G(整个堆的大小)的hprof文件
- 服务器访问慢,可能就是系统快要崩溃了,系统崩溃前垃圾回收特别慢,就会造成服务器反应慢啊!!!
怎么触发 Java heap dump(生成内存快照)
- 使用$JAVA_HOME/bin/jmap -dump来触发,eg:jmap -dump:format=b,file=/home/longhao/heamdump.out
- 使用$JAVA_HOME/bin/jcosole中的MBean,到MBean>com.sun.management>HotSpotDiagnostic>操作>dumpHeap中,点击 dumpHeap按钮。生成的dump文件在java应用的根目录下面。
- 在应用启动时配置相关的参数 -XX:+HeapDumpOnOutOfMemoryError,当应用抛出OutOfMemoryError时生成dump文件。
- 使用hprof。启动虚拟机加入-Xrunhprof:head=site,会生成java.hprof.txt文件。该配置会导致jvm运行非常的慢,不适合生产环境。
为什么崩溃前垃圾回收的时间越来越长
根据内存模型和垃圾回收算法,垃圾回收分两部分:内存标记、清除(复制),标记部分只要内存大小固定时间是不变的,变的是复制部分,因为每次垃圾回收都有一些回收不掉的内存,所以增加了复制量,导致时间延长。所以,垃圾回收的时间也可以作为判断内存泄漏的依据
为什么Full GC的次数越来越多
因此内存的积累,逐渐耗尽了年老代的内存,导致新对象分配没有更多的空间,从而导致频繁的垃圾回收
为什么年老代占用的内存越来越大
因为年轻代的内存无法被回收,越来越多地被Copy到年老代
分享到:
相关推荐
在 ARM 服务器环境下,JVM 垃圾回收面临着一些特殊的挑战。首先,由于 ARM 服务器通常具有有限的存储空间,因此垃圾回收需要更加高效地利用内存资源。其次,ARM 服务器的处理效率相对较低,因此垃圾回收过程不能对...
《JVM垃圾回收艺术——探索Tenured Generation的内涵》 在深入探讨JVM垃圾回收机制的艺术之前,我们先来理解一下“天才”的定义——一种对事业、对工作的极度热爱。JAVA垃圾回收(GC)同样展现出这种对效率和优化的...
通过对垃圾回收机制的理解,开发者可以更加有效地管理内存资源,避免常见的内存泄漏问题,并在遇到性能瓶颈时能够快速定位问题所在。未来,随着技术的发展,垃圾回收机制也将不断优化和完善,为Java开发者提供更加...
1.5 JVM调优总结(四)-垃圾回收面临的问题 12 1.6 JVM调优总结(五)-分代垃圾回收详述1 14 1.7 JVM调优总结(六)-分代垃圾回收详述 1.8 JVM调优总结(七)-典型配置举例 1.9 JVM调优总结(八)-典型配置举例2 31 ...
9. **内存溢出问题**:如果垃圾回收无法释放足够的内存,程序可能会遇到OOM(Out Of Memory)错误,这通常需要检查代码中的内存使用情况,或者调整JVM的内存分配策略。 10. **现代JVM优化**:随着JVM的发展,如G1...
Java垃圾回收(Garbage Collection, 简称GC)是JVM(Java Virtual Machine)管理内存的重要机制。在Java应用程序运行过程中,如果发现并回收不再使用的对象,可以防止内存泄漏,确保程序稳定运行。当我们遇到应用...
4. **主人定期捕鱼-JVM垃圾回收** 垃圾回收是JVM自动清理不再使用的对象的过程,分为Minor GC(针对年轻代)和Major / Full GC(针对老年代或整个堆)。不同的垃圾回收器(如Serial、Parallel、CMS、G1等)有不同...
- **垃圾回收器面临的主要问题**: - **哪些对象需要回收?** - **何时回收这些对象?** - **如何回收这些对象?** - **垃圾回收的意义**: - 在C++等语言中,对象占用的内存直到程序结束才会被释放,在此期间...
垃圾回收面临的问题包括处理速度、暂停时间和内存碎片等问题。 在典型配置举例部分,文档提供了实例来说明如何设置JVM参数来优化垃圾回收和内存分配。此外,文档还提到了新一代垃圾回收算法,例如G1垃圾回收器,它...
Java虚拟机(JVM)中的垃圾回收(Garbage Collection,简称GC)是自动管理内存的重要机制,它负责识别并回收那些不再使用的对象所占据的内存,以防止内存泄漏和资源浪费。理解GC的相关概念对于优化Java应用的性能至...
通过这些工具可以监控JVM内存状态(heap、non-heap、codecache等)、线程状态、堆栈状态、垃圾回收情况以及CPU负载等关键指标。 #### 系统思考 对于JVM问题的定位,除了依赖于具体的工具之外,还需要具备一定的...
垃圾回收主要涉及两个核心问题: 1. **如何判断一个对象是否成为垃圾?** 2. **如何有效地回收这些垃圾对象所占用的内存?** 针对第一个问题,有两种常用的判断方法:**引用计数**和**可达性分析**。 ##### 引用...
理解JVM的基本原理,如内存模型、垃圾回收机制等,不仅有助于写出更高效的代码,还能更好地解决实际开发中遇到的各种问题。随着技术的发展,JVM也在不断改进和优化,例如引入了更多的垃圾回收器选项(如G1、ZGC等)...
通过这些工具,我们可以定位性能瓶颈,比如频繁的垃圾回收导致的暂停时间过长,或者内存泄漏问题。 此外,JVM中的垃圾回收机制也是优化的关键。了解不同的垃圾收集器,如Serial、Parallel、CMS和G1,以及它们各自的...
- **垃圾回收机制**:JVM通过自动垃圾回收机制来管理对象的生命周期,了解其工作原理有助于优化内存使用。 - **类加载机制**:类加载是JVM启动后的一个重要环节,理解类加载过程对于解决类加载问题具有重要意义。 ...
《Garbage-First Garbage Collection》这篇论文不仅详细介绍了G1垃圾回收器的设计思想和技术特点,还展示了如何通过先进的垃圾回收技术解决大型服务器应用所面临的挑战。G1垃圾回收器通过并发标记、区域划分、并行...
当JVM遇到问题,如内存溢出或长时间的垃圾回收,它可能会生成堆栈转储(dump)文件,这些文件包含了JVM在特定时刻的详细状态,包括对象、类加载器、线程、堆和栈信息。"Jvm堆栈dump文件分析"是指通过特定工具对这些...
例如,节点可能会因为JVM垃圾回收(GC)问题而表现异常,比如“younggc”和“oldgc”频繁发生,或者垃圾回收时间过长。这些现象通常提示我们对Heap内存分配和GC参数进行优化调整。Young GC通常指的是Eden区域的回收...