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

JVM内存分配、垃圾回收、启动参数

阅读更多
一、Java内存组成
  1. 组成图
  2. 堆(Heap)
    1. 运行时数据区域,所有类实例和数组的内存均从此处分配。Java虚拟机启动时创建。对象的堆内存由称为垃圾回收器的自动内存管理系统回收。
    2. 组成 组成 详解
      Young Generation 即图中的Eden + From Space + To Space
      1.Eden存放新生的对象
      2.Survivor Space有两个,存放每次垃圾回收后存活的对象
      Old Generation Tenured Generation 即图中的Old Space
      主要存放应用程序中生命周期长的存活对象
  3. 非堆内存
    1. JVM具有一个由所有线程共享的方法区。方法区属于非堆内存。它存储每个类结构,如运行时常数池、字段和方法数据,以及方法的代码。它是在Java虚拟机启动时创建的。
    2. 除了方法区外,Java虚拟机实现可能需要用于内部处理或优化的内存,这种内存也是非堆内存。例如,JIT编译器需要内存来存储从Java虚拟机代码转换而来的本机代码,从而获得高性能。
    3. 组成 组成 详解
      Permanent Generation 即图中的Permanent Space
      存放JVM自己的反射对象,比如类对象和方法对象
      native heap JVM内部处理或优化
二、GC策略
    1. JVM采用一种分代回收(generational collection)的策略,用较高的频率对年轻的对象(young generation)进行扫描和回收,这种叫做minor collection,而对老对象(old generation)的检查回收频率要低很多,称为major collection。这样就不需要每次GC都将内存中所有对象都检查一遍。
  1. 非堆内存
    1. GC不会在主程序运行期对PermGen Space进行清理,所以如果你的应用中有很多CLASS的话,就很可能出现PermGen Space错误。
三、内存申请、对象衰老过程
  1. 内存申请过程
    1. JVM会试图为相关Java对象在Eden中初始化一块内存区域;
    2. 当Eden空间足够时,内存申请结束。否则到下一步;
    3. JVM试图释放在Eden中所有不活跃的对象(minor collection),释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区;
    4. Survivor区被用来作为Eden及OLD的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区;
    5. 当OLD区空间不够时,JVM会在OLD区进行major collection;
    6. 完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现"Out of memory错误";
  2. 对象衰老过程
    1. young generation的内存,由一块Eden和两块Survivor Space构成。新创建的对象的内存都分配自eden。两块Survivor Space总有会一块是空闲的,用作copying collection的目标空间。Minor collection的过程就是将eden和在用survivor space中的活对象copy到空闲survivor space中。所谓survivor,也就是大部分对象在Eden出生后,根本活不过一次GC。对象在young generation里经历了一定次数的minor collection后,年纪大了,就会被移到old generation中,称为tenuring。
    2. 剩余内存空间不足会触发GC,如eden空间不够了就要进行minor collection,old generation空间不够要进行major collection,permanent generation空间不足会引发Full GC。
四、JVM参数
  1. 参数说明 参数 说明 默认值 生产环境约定
    -Xms/-Xmx 定义YOUNG+OLD段的总尺寸,ms为JVM启动时YOUNG+OLD的内存大小;mx为最大可占用的YOUNG+OLD内存大小。 默认是物理内存的1/64但小于1G。 在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。
    -XX:NewSize/-XX:MaxNewSize 定义YOUNG段的尺寸,NewSize为JVM启动时YOUNG的内存大小;MaxNewSize为最大可占用的YOUNG内存大小。 默认是物理内存的1/4但小于1G。 在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。
    -Xmn 设置young generation的内存大小。 整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
    -XX:PermSize/-XX:MaxPermSize 定义Perm段的尺寸,PermSize为JVM启动时Perm的内存大小;MaxPermSize为最大可占用的Perm内存大小。 在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。
    -XX:NewRaito
    设置YOUNG与OLD段的比值。

    -XX:SurvivorRaito
    设置YOUNG段中Eden区与Survivor区的比值,如此值为4,则Eden为4/6,两个Survivor分别为1/6。
    -XX:MaxTenuringThreshold
    设置垃圾最大年龄。
    如果设置为0的话,则新生对象不经过Survivor区,直接进入OLD段。对于OLD对象比较多的应用,可以提高效率。如果将此值设置为一个较大值,则 新生对象会在Survivor区进行多次复制,这样可以增加对象的存活时间,增加在minor collection即被回收的概率。
    -Xss 设置栈的大小。
    JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。 在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
    -XX:+UseParallelGC 选择垃圾收集器为并行收集器。此配置仅对年轻代有效。即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集。
    -XX:ParallelGCThreads
    配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。 此值最好配置与处理器数目相等。
    -XX:+UseParallelOldGC
    配置年老代垃圾收集方式为并行收集。JDK6.0支持对年老代并行收集。
    -XX:MaxGCPauseMillis
    设置每次年轻代垃圾回收的最长时间,如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值。
    -XX:+UseAdaptiveSizePolicy
    设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低相应时间或者收集频率等。 此值建议使用并行收集器时,一直打开。
  2. 举例说明
    MEM_ARGS="-Xms512m -Xmx512m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=128m -XX:MaxPermSize=128m -XX:SurvivorRatio=6"
    
    

    上例中,
    YOUNG+OLD: 512M
    YOUNG: 256M
    Perm: 128M
    Eden: YOUNG*6/(6+1+1)=192M
    单个Survivor: YOUNG/(6+1+1)=32M

分享到:
评论

相关推荐

    JVM内存空间分配笔记

    ### JVM内存空间分配详解 #### 一、JVM内存模型概览 ...综上所述,理解JVM内存分配机制对于Java开发者来说至关重要,这不仅有助于编写高效、稳定的代码,还能在遇到性能瓶颈时快速定位问题并进行优化。

    03-VIP-JVM内存分配机制与垃圾回收算法1

    4. **JVM内存分配示例分析** 在提供的代码示例中,我们看到当分配给`allocation1`的大对象超过Eden区的容量时,JVM执行了Minor GC。初始时,Eden区被完全使用,而老年代未使用。当我们尝试为`allocation2`分配内存...

    JVM初始分配的内存.doc JVM初始分配的内存.doc

    - **意义**:合理设置初始堆内存大小有助于优化JVM的启动时间,并且可以避免由于初始堆内存过小导致的频繁垃圾回收问题。 ##### 2. `-Xmx`: 最大堆内存大小 - **定义**:指定了JVM运行过程中所能使用的最大堆内存...

    idea插件JVM内存工具JProfiler11

    2. **垃圾收集分析**:JProfiler11提供了GC日志分析,可以观察不同垃圾收集器的执行频率和效果,帮助优化垃圾回收策略,减少不必要的暂停时间。 3. **线程和同步分析**:线程状态的实时监控对于找出死锁和资源争抢...

    Java内存分配及垃圾回收文章汇总

    Java内存分配与垃圾回收是Java程序性能优化的关键领域。在Java平台上,程序的运行主要依赖于JVM(Java虚拟机),而JVM的核心组件之一就是内存管理。本篇将深入探讨Java内存分配策略以及垃圾回收机制,以帮助你更好地...

    jvm_gc.rar_jvm_垃圾回收

    了解JVM内存模型和垃圾回收机制对于Java开发人员来说非常重要,可以帮助解决内存溢出、性能瓶颈等问题,提升程序的稳定性和效率。通过深入学习这些概念,可以更好地理解和控制Java程序在运行时的行为。

    JVM-内存管理 2012-12.pdf

    老年代用于存放经过多次垃圾回收仍然存活的对象。 内存分配指的是当应用程序创建对象时,JVM会为对象分配内存。这个过程对Java程序员来说是透明的,通常不需要干预。对象通常在Java堆的新生代的Eden区创建,当Eden...

    09 Java基础-JVM垃圾回收-玉峰1

    为了优化JVM内存使用,开发者需要根据应用需求设置合适的启动参数,如`-Xms`和`-Xmx`分别指定堆内存的初始和最大值,`-XX:PermSize`和`-XX:MaxPermSize`(在JDK 8之前)用于设置方法区大小。 总之,理解JVM的内存...

    JVM内存管理面试常见问题全解.doc

    JVM 调优是 JVM 的性能优化,JVM 调优的核心参数包括堆的大小、年轻代的大小、垃圾回收器的选择、垃圾回收的频率等。JVM 调优的目的是提高 JVM 的性能,降低垃圾回收的暂停时间。 九、JVM 性能调优的原则 JVM 性能...

    09.内存分配与回收策略1

    JDK 1.8默认使用的垃圾回收器是Parallel Scavenge + Parallel Old,因此使用以上参数的时候,需要调整为Serial或ParNew收集器。使用-XX:+PrintCommandLineFlags JVM参数可以查看默认设置收集器的类型。

    如何配置Tomcat的JVM虚拟机内存大小

    通过对`-Xms`、`-Xmx`等参数的细致调整,结合适当的垃圾回收策略,以及合理设置连接器参数,可以显著增强Tomcat服务器的稳定性和效率。在实践中,持续监控应用的运行状况,根据实际需求动态调整配置,是实现最优性能...

    JVM内存模型

    为了更好地监控和调整JVM的内存使用情况,可以利用一系列JVM参数来查看和调整内存分配情况,主要包括: - **程序计数器**:记录线程下一条要执行的指令位置。 - **堆**:线程共享,用于存储对象实例和数组。 - **...

    MyEclipse内存不足谈谈JVM内存

    它是Java应用程序的主要存储区域,也是垃圾回收器主要工作的区域。JVM在启动时会自动分配堆内存。 - **非堆内存(Non-Heap)**:也被称为永久代(Permanent Generation)或者元空间(Metaspace),用于存储类定义、常量池...

    Tomcat JVM的参数调优

    【标题】"Tomcat JVM参数调优...总的来说,JVM参数调优是一个涉及内存分配、垃圾回收效率和系统资源平衡的复杂过程。适当的调优能确保Tomcat在处理大量并发请求时保持高效和稳定,同时避免内存问题导致的服务中断。

    jvm调优实战经验

    调整JVM参数可以控制内存分配、垃圾回收策略、并行度等,例如 `-Xms` 和 `-Xmx` 设定堆内存大小,`-XX:NewRatio` 控制年轻代和老年代的比例,`-XX:+UseConcMarkSweepGC` 开启CMS垃圾回收器等。通过监控工具(如...

    内存分配源代码MemoryAllocation.rar

    7. **JVM调优**:通过调整JVM的启动参数,如堆大小、新生代与老年代的比例、GC策略等,可以影响内存分配的效率和程序的整体性能。 这个源代码可能是对以上某个或多个方面进行的示例演示或实验,帮助学习者理解内存...

Global site tag (gtag.js) - Google Analytics