`
liuzhaodong89
  • 浏览: 60371 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JVM GC浅谈

    博客分类:
  • jvm
阅读更多

jvm中的内存可以分为堆内存和非堆内存,其中堆内存用于存储虚拟机运行中产生的各种对象,而通常所说的GC也就是针对这一块内存而言的。作为开发者,我们并不需要去关心到底什么时候该调用GC去清理内存,因为jvm会帮我们打理好这一块。但是如果想深入了解java内存管理,就不得不关心下这块对程序员“透明”的区域了。

 

要了解GC过程,首先要说说堆内存是怎么工作的。java所创建的对象会都放在堆内存中,但随着新对象的逐渐加入,堆内存的剩余空间会越来越少。当无法给一个新的对象继续分配内存空间时,程序就会发生out of memory。我们知道,java程序员在编写时无需关心何时释放对象的内存,所以会有相当一部分的“垃圾”对象,即再也不会引用到的对象存在于内存中。当剩余空间不够时,jvm就会扫描堆内存找出垃圾对象,将其占用的内存释放掉,这就是GC。

 

jvm中的GC采用了generation算法,认为内存中的对象有这样的情形:大多数的对象存活的时间比较短,而少部分的对象才能够长时间存活。因此,jvm将堆内存划分为年轻代(young generation)和年老代(old generation)。年轻代中的对象通常建立时间不久,且大部分生命周期也很短;年老代中的对象则已经创建比较久了,其声明周期也相对年轻代比较长。按照上面的划分,jvm在做GC时也进行了区别对待,对年轻代GC会相对比较频繁,且采用了copying算法;年老代的GC相对比较少,且采用的是tracing算法的一种,是标记-清除-压缩。

具体结构如下图:

堆内存结构

Young Generation——当一个对象被创建时,需要给其分配内存。由于堆内存是所有java线程共享的,所以如果要分配一段内存空间就必须先对内存加锁,这样是很耗性能的,故如果对象所需内存小于某个值(好像是512个字节,我也忘了)直接从线程自己的缓存里分配。如果在Young Generation中分配内存的话,就通常是放在Eden(伊甸园区,不知道为啥取这个名字)中。这里就要介绍下Young Generation中内存的划分和使用了:

        Eden——所有新创建的对象都被放置在这里。

        Survivor——当Eden区空间不足时,会将其中依旧存活的对象拷贝到两块Survivor区域(FromSpace和                     ToSpace)中的一个,如果此时这个Survivor区域也空间不足,则将该块区域中存活的对象拷贝到另一块区域中。           注意,总有一个Survivor区域是空的。

对Young Generation的垃圾回收叫minor GC,通常很多的对象都活不过一次GC。

 

Old Generation——但一个Survivor区域满了的时候,会将该区域中已经历一定次数GC而依旧存活的对象放到Old Generation中。如果Old Generation也满了,那就要Full GC了。Full GC很耗性能,当Full GC进行时,应用程序会暂停。由于大部分对象都活不过一次GC,所以如果服务器上频繁的发生Full GC,就要关注下是不是出问题了。

 

Permanent Generation——这块区域我认为就是方法区,其作用就是用来存放java类、方法信息和常量池等。有的观点也将方法区看做是Permanent Generation,并看做堆内存一部分,这里就顺便介绍下。通常这块内存不会有什么太大的变动,当然如果采用了动态生成一些类的方式来设计应用程序,那么这块也需要设置较大一些用来放置新增的类。另外,由于常量池也放在这块区域里,所以如果常量池无限增大,理论上也会出现oom。也正因为这样,这块区域也会有GC,而且方式是Full GC。

 

上面就是jvm GC的一些信息。当然,开发人员也可以通过设置参数来影响jvm对内存的管理,下面就是一些常用的参数:

-Xmx——Heap区域最大值。默认为系统内存的1/4,不超过1G。

-Xms——Heap区域初始化时候的内存值。默认为系统的1/64,不超过1G。如果当前的空余堆内存比例小于40%(见-XX:MinHeapFreeRatio)系统会将堆内存扩大到最大值。通常-Xmx和-Xms设置为一样的值,免得内存来回变动损耗性能。

-XX:PermSize——设置方法区的内存初始值,通常为系统内存的1/64。

-XX:MaxPermSize——设置方法区的最大内存值,通常为系统内存的1/4。

-XX:MinHeapFreeRatio——设置Heap区域最小空闲值,用于控制何时将堆内存扩大至最大值,通常是40%

-XX:MaxHeapFreeRatio——设置Heap区域最大空闲值,用于控制何时将对内存缩小至初始值,通常是70%

-XX:NewRatio——设置Heap区域中new和old代大小的比例,值就是年轻代内存大小/年老代内存大小。

-XX:SurvivorRatio——设置Survivor区域和Eden区域的比例,值就是Eden区域大小/Survivor区域大小。

分享到:
评论

相关推荐

    浅谈Java堆外内存之突破JVM枷锁

    浅谈Java堆外内存之突破JVM枷锁 本文主要介绍了Java堆外内存的概念,包括JVM内存分配、JVM垃圾回收、堆外内存的垃圾回收等相关内容。Java开发者都知道,Java中不需要手动申请和释放内存,JVM会自动进行垃圾回收;而...

    浅谈jvm中的垃圾回收策略

    Java虚拟机(JVM)中的垃圾回收(Garbage Collection, GC)是自动内存管理的关键机制,它负责识别并清理不再使用的对象,以便回收内存资源。本文将深入探讨JVM的垃圾回收策略,尤其是基于分代的内存回收算法。 在...

    java gc调优

    在《浅谈JVM内存管理》的PPT中,可能包含了对上述概念的详细讲解,包括JVM内存模型的解析、GC算法的工作原理、如何配置和调整GC参数,以及通过实例分析GC调优的具体步骤。通过学习这个PPT,开发者可以深入理解JVM...

    浅谈JAVA垃圾回收机制.pdf

    浅谈 JAVA 垃圾回收机制 Java 垃圾回收机制是 Java 语言中的一种自动内存管理机制,它可以自动回收内存中的垃圾,避免代码运行时由于忘记释放对象而带来的内存泄漏问题。 Java 中的垃圾回收机制主要通过两种算法来...

    浅谈关于Java的GC垃圾回收器的一些基本概念

    Java的垃圾回收(GC)是Java虚拟机(JVM)管理内存的重要机制,它自动识别并清理不再使用的对象,以防止内存泄漏。本文主要探讨Java GC的基本概念,涉及JVM内存模型以及不同的垃圾回收算法。 首先,让我们了解几种...

    浅谈java内存管理与内存溢出异常

    而在Java中,JVM自动管理内存,使用垃圾收集器(Garbage Collector, GC)来自动回收不再使用的对象,从而减轻了程序员的负担。然而,尽管如此,理解JVM的内存结构对于识别和解决内存问题至关重要。 JVM运行时数据区...

    浅谈java的守护线程与非守护线程

    浅谈java的守护线程与非守护线程 在Java中,有两类线程:UserThread(用户线程)和Daemon Thread(守护线程)。守护线程的作用是为其他线程的运行提供服务,比如说GC线程。它们的本质上来说没有区别,唯一的区别...

    浅谈Java垃圾回收的实现过程

    通过这一自动化过程,JVM解除了程序员在程序中分配和释放内存资源的开销。启动Java垃圾回收作为一个自动的过程,程序员不需要在代码中显示地启动垃圾回收过程。 Java垃圾回收的实现过程可以分为以下几个阶段: 1. ...

    浅谈Java编程中的内存泄露情况

    本文将深入探讨Java中的内存泄露及其相关的JVM垃圾回收机制。 首先,与C++等语言不同,Java引入了垃圾回收(Garbage Collection, GC)机制,自动负责管理内存,避免程序员手动释放内存可能导致的错误。然而,这并不...

    关于Flume的优化和高可用

    例如,在`flume-env.sh`配置文件中添加`JAVA_OPTS="-Xms512m -Xmx1024m"`,确保JVM堆内存的初始和最大值一致。此外,根据系统资源和负载情况,考虑将JVM heap设置为4GB或更高,以提供足够的空间处理大规模数据。 二...

    通过String.intern()方法浅谈堆中常量池

    这个方法的主要功能是检查当前字符串对象的值是否已经在Java虚拟机(JVM)的字符串常量池中存在。如果存在,它会返回常量池中的引用;如果不存在,它会将当前字符串的引用放入常量池,并返回这个新添加的引用。 在...

    关于javal垃圾回收机制的一些文档

    浅谈Java垃圾回收机制.doc文档可能会涵盖以下几个关键点: 1. **对象生命周期**:当一个对象被创建后,它会在内存中占据一定的空间。如果对象不再被任何引用指向,那么这个对象就成为垃圾。 2. **垃圾收集器**:...

Global site tag (gtag.js) - Google Analytics