`
truelove12358
  • 浏览: 77617 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

JVM内存模型和性能优化

 
阅读更多

JVM内存模型优点

  1. 内置基于内存的并发模型: 多线程机制
  2. 同步锁Synchronization
  3. 大量线程安全型库包支持
  4. 基于内存的并发机制,粒度灵活控制,灵活度高于数据库锁。
  5. 多核并行计算模型
  6. 基于线程的异步模型。

JVM性能的人为问题

  1. 关键原因是:没有正确处理好对象的生命周期。
  2. 需要从需求中找出存在自然边界的业务对象,将其对应落实到内存中,成为内存模型In-memory Domain Model。
  3. 有大小边界限制的内存是缓存,没有永远使用不完的内存,缓存=“有边界的”内存。
  4. 缓存是Domain Model对象缓存,不同于传统意义上数据库缓存的定义。
  5. 分布式缓存可以提高巨量数据处理计算能力。

Java内存种类

  1. Stack栈内存
    存取速度快,数据可多线程间共享。
    存在栈中的数据大小与生存期必须确定
  2. Heap堆内存
    大小动态变化,对象的生命周期不必事先告诉编译器JVM。

两种内存使用

  1. Stack栈内存
    基本数据类型,Java 指令代码,常量
    对象实例的引用 对象的方法代码
  2. Heap堆内存
    对象实例的属性数据和数组。堆内存由Java虚拟机的自动垃圾回收器来管理。

对象如何保存在内存中?

  1. 对象的属性Attribute Property

属性值作为数据,保存在数据区heap 中,包括属性的类型Classtype和对象本身的类型

  1. 方法method

方法本身是指令的操作码,保存在stack中。
方法内部变量作为指令的操作数也是在Stack中,
包括基本类型和其他对象的引用。

  1. 对象实例在heap 中分配好内存以后,需要在stack中保存一个4字节的heap内存地址,用来定位该对象实例在heap 中的位置,便于找到该对象实例。

静态属性和方法的特点

  1. 静态属性和方法都是保存在Stack中,
  2. Stack内存是共享的,其他线程都可以访问静态属性实际是全局变量。
  3. 静态方法在Stack,就无法访问Heap中的数据。静态方法无法访问普通对象中数据。
  1. 静态属性意味着全局变量,生命周期和JVM一致。JVM属于技术边界,静态只能用于技术边界内工具性质使用,不能用作业务。

内存管理:垃圾回收机制

  1. 每一种垃圾收集的算法(引用计数、复制、标记-清除和标记-整理等)在特定条件下都有其优点和缺点。
  2. 当有很多对象成为垃圾时,复制可以做得很好,但是复制许多生命周期长的对象时它就变得很糟(要反复复制它们)。
  3. 标记-整理适合生命周期长对象可以做得很好(只复制一次),但是不适合短生命的对象。
  4. Sun JVM 1.2 及以后版本使用的技术称为 分代垃圾收集(generational garbage collection),它结合了这两种技术以结合二者的长处。

可选用的GC类型

jvm参数


JVM性能优化

  1. 内存微调优化
  1. 锁争夺微调:

多线程 不变性 单写原则 Actor Disrupotor

  1. CPU使用率微调
  1. I/O 微调

内存微调优化

  1. 内存分配:

新生代 Eden和survior 旧生代内存大小分配。
内存越大,吞吐量越大,但是需要内存整理的时间就越长,响应时间有延迟。

  1. 垃圾回收机制

垃圾回收启动整个应用都暂停,暂停时间造成响应时间有延迟。


内存微调目标

  1. 在延迟性(响应时间)和吞吐量上取得一个平衡。
  1. 内存大小影响吞吐量和延迟性。需要在内存大小和响应时间之间取得一个平衡。
  1. 垃圾回收机制是延迟的最大问题。目标尽量不启动,少启动。


内存模型

新生代Eden内存分配

  • 新生代(New Generation ):Eden + 1 Survivor。所有新创建的对象在Eden。
  • 当Eden满了,启动Stop-The-World的GC,或为minor gc,采取数次复制Copy-Collection到Survivor。
  • 经过几次收集,寿命不断延长的对象从Survivor 进入老生代,也称为进入保有Tenuring,类似普通缓存LRU算法。


survivor设计要旨

  1. 足够大到能容纳所有请求响应中涉及的对象数据。
  1. 每个survivor空间也要足够大到能够容纳活跃的请求对象和保有对象。
  1. Survivor大小决定了保有Tenuring阀值,阀值如果能大到容纳所有常住对象,那么保有迁移过程就越快。

老生代Old

  1. 老生代的gc称为major gc,就是通常说的full gc。
  2. 采用标记-整理算法。由于老年区域比较大,而且通常对象生命周期都比较长,标记-整理需要一定时间。所以这部分的gc时间比较长。
  3. minor gc可能引发full gc。当eden+from space的空间大于老生代的剩余空间时,会引发full gc。这是悲观算法,要确保eden+from space的对象如果都存活,必须有足够的老生代空间存放这些对象。
  4. 这些都根据情况调整启动JVM的设置。
  5. 使用 Adaptive让JVM自动划分新生代和老生代。

Permanent Generation 永久代

  1. 该区域比较稳定,主要用于存放classloader信息,比如类信息和method信息。
  2. 缺省是64M ,如果你的代码量很大,容易出现OutOfMemoryError: PermGen space。
  3. 2G以上内存设置MaxPermSize为160M
  4. -XX:PermSize=128m -XX:MaxPermSize=160m

降低Full GC发生概率

  1. 为了降低Full GC发生概率,如果降低了老生代大小,那么OutOfMemoryError发生,Full GC概率反而会上升。
  2. 如果为了降低Full GC,增加老生代大小,执行时间可能会被延长。
  3. 必须寻找合适大小的老生代。
  4. 避免大的对象迁移到老生代。
  5. 减少迁移到老生代的对象数目

java.lang.OutOfMemoryError

  1. (1)在高负荷的情况下的却需要很大的内存,因此可以通过修改JVM参数来增加Java Heap Memory。
  2. (2)应用程序使用对象或者资源没有释放,导致内存消耗持续增加,关键采取OO封装边界方式,树立对象都有生命周期的基本习惯。
  3. (3)再一种也可能是对于第三方开源项目中资源释放了解不够导致使用以后资源没有释放(例如JDBC的ResultSet等)。

JVM参数

  1. -Xms, -Xmx—定义JVM的heap大小最小和最大值。
  1. -XX:NewSize— 定义年轻态的最小大小,Eden越大越好,但是越大响应有延迟。

  1. -Xmx2G -Xms1G -XX:NewSIze=512M (OldGen at least 1G)
  2. -Xmx3G -Xms1G -XX:NewSize=512M (OldGen at least 2G)
  3. Xmx4G -Xms2G -XX:NewSize=1G (OldGen at least 2.5G)
  4. -Xmx6G -Xms3G -XX:NewSize=2G (OldGen at least 3.5G)
  5. -Xmx8G -Xms4G -XX:NewSize=3G (OldGen at least 4.5G)

参数调整示意

  1. JAVA_OPTS="$JAVA_OPTS -server -Xss1280K -Xms1664m -Xmx1664m -XX:MaxPermSize=128m -XX:SurvivorRatio=16 -XX:NewSize=1280m -XX:MaxNewSize=1280m -XX:+DisableExplicitGC -XX:GCTimeRatio=2 -XX:ParallelGCThreads=4 -XX:+UseParNewGC -XX:MaxGCPauseMillis=2000 -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=80 -XX:+CMSClassUnloadingEnabled


Survivor大小

  1. NewSize / ( SurvivorRatio + 2)
  2. 如果SurvivorRatio =16, NewSize =1280m,那么S大小是70M。
  3. 太小,溢出的复制Collection进入老生代。
  4. 太大,闲置无用 浪费内存。
  5. 使用XX:+PrintTenuringDistribution 和-XX:+PrintGCDetails, -XX:+PrintHeapAtGC观察:
  6. -XX:+UseAdaptiveSizePolicy冲突


垃圾回收机制启动

  1. 垃圾回收机制不会频繁启动,因为机制一旦启动,造成应用程序停顿。
  2. 机制一般内存剩余5%左右启动,所以有现象:启动服务器,内存不断消耗,有多大内存消耗多大。
  3. 问题:如果服务器程序频繁触及5%底线,机制频繁启动,造成服务器慢..甚至死机。
  4. 根源:应用程序无限制频繁大量创建对象,消耗内存。

控制垃圾回收

  1. 带CMS参数的都是和并发回收相关的
  2. -XX:+UseParNewGC,对新生代采用多线程并行回收。
  3. CMSInitiatingOccupancyFraction=90说明年老代到90%满的时候开始执行对年老代的并发垃圾回收(CMS)
  4. 用jmap和jstack查看

串行 并行回收的区别

  1. 新生代 高吞吐量:
  2. -XX:+UseSerialGC
    -XX:+UseParallelGC
    -XX:+UseParNewGC
  3. 老生代 低暂停:
  4. -XX:+UseParallelOldGC
    -XX:+UseConcMarkSweepGC
  5. 相同点:GC时都暂停一切。
  6. 不同点:一个线程和多个线程同时GC

并行和CMS(Concurrent-Mark-Sweep)区别

  1. CMS步骤:
  2. - initial mark
    - concurrent marking
    - remark
    - concurrent sweeping
  3. 区别:CMS一个线程,并行多个线程
  4. CMS只是在1 3阶段暂停,而并行全部暂停。

Parallel GC 和 CMS GC

  1. 压实compaction是移除内存碎片,也就是移除已经分配的内存之间的空白空间。
  2. 在Parallel GC中,无论Full GC是否执行,压实总是被执行,会花费更多时间,不过在执行完Full GC后,内存也许再被使用时,会分配得快些,能够顺序分配了。
  3. CMS GC 并不执行压实,所以更快,碎片太多,没有空间放置大的需要连续空间的对象,“Concurrent mode failure”会发生。

并行和CMS配置

  1. -XX:UserParNewGC 适合于

新生代 (multiple GC threads)
-XX:+UseConcMarkSweepGC 适合于
老生代 (one GC thread, freezes the JVM only during the initial mark and remark phases)
-XX:InitiatingOccupancyFraction 80是表示CMS是在老生代接近满80%启动,如CPU空闲,可设定点一些。

-XX:+CMSIncrementalMode 用于CMS,不会让处理器Hold住整个并发phases 。

下页

JVM有关垃圾回收机制的配置

可视化JVM参数设置

生产环节下JVM运营监测

完整的JVM -xx参数对照表

Tomcat实战中的微调

服务器后端性能大比拼

Java多线程设计要点

多线程

同步或锁

Java性能测试

Java性能调优

高性能

可伸缩性

JVM专题讨论

分享到:
评论

相关推荐

    JVM内存模型和性能优化.docx

    Java虚拟机(JVM)内存模型是Java编程中至关重要的...总之,理解和优化JVM内存模型对于提升Java应用的性能至关重要。开发者需要根据应用的具体需求和场景,精细化调整内存分配和垃圾回收策略,以达到最佳的运行效果。

    JVM内存模型深度剖析与优化.pdf

    本文将深入剖析JVM内存模型的结构和工作机理,并讨论如何优化JVM参数以提高Java应用程序的性能。 一、JVM内存模型结构 JVM内存模型主要分为以下几个部分: 1. 程序计数器(PC Register):存储当前线程执行的字节...

    JVM内存模型

    JVM内存模型详解 JVM内存模型是Java虚拟机(JVM)中的一种内存管理机制,它将内存区分为永久区内存(Permanent ...通过了解JVM内存模型和对JVM的优化,可以避免内存溢出异常的发生,提高Java应用程序的性能和可靠性。

    jvm性能调优-jvm内存模型和优化-performance-jvm-memorymodel-optimize.zip

    JVM内存模型的理解和优化,对于解决性能瓶颈、避免内存泄漏以及提高系统稳定性至关重要。本文将详细探讨JVM的内存结构,以及如何进行有效的调优。 一、JVM内存结构 1. **程序计数器(Program Counter Register)**...

    JVM内存模型以及垃圾回收相关资料

    JVM内存模型与垃圾回收是Java性能优化的关键部分。JVM(Java Virtual Machine)内存模型分为多个区域,包括新生代(New Generation)、老年代(Old Generation)和永久代(Permanent Generation)。新生代又细分为...

    推荐一些JVM原理,JVM调优,JVM内存模型,JAVA并发 电子书1

    总的来说,JVM原理、JVM调优、JVM内存模型和JAVA并发是Java程序员和系统管理员需要深入了解的知识点,因为它们直接影响到Java程序的性能和稳定性。了解这些知识点有助于开发者编写性能更优的代码,并在生产环境中对...

    深入理解Java虚拟机(jvm性能调优+内存模型+虚拟机原理).zip

    《深入理解Java虚拟机》是一本深度探讨Java虚拟机(JVM)的著作,涵盖了JVM性能调优、内存模型以及虚拟机原理等多个关键领域。本文将基于这些主题,详细阐述其中的重要知识点。 首先,我们要了解Java虚拟机(JVM)...

    实战JAVA虚拟机 JVM故障诊断与性能优化

    二、JVM内存模型 JVM内存分为堆内存、栈内存、方法区、程序计数器和本地方法栈五大部分。堆内存用于存储对象实例,栈内存处理方法调用,方法区存储类信息,程序计数器记录下一条指令地址,本地方法栈服务于Java的...

    (主讲视频)JVM原理、内存模型、性能调优

    JVM内存模型主要包括以下几个部分: 1. **程序计数器(Program Counter Register)**:当前线程所执行的字节码的行号指示器。每个线程都有一个私有的程序计数器。 2. **Java虚拟机栈(Java Virtual Machine Stacks)**...

    实战Java虚拟机 JVM故障诊断与性能优化 葛一鸣

    4. **性能优化**:JVM性能优化主要包括内存优化、线程优化、代码优化和JVM参数调整。例如,合理设置堆大小、新生代与老年代的比例,选择合适的GC策略,避免死锁和竞态条件,以及利用JDK工具(如JVisualVM、JProfiler...

    Java 虚拟机JVM内存模型

    通过以上对JVM内存模型和垃圾收集策略的分析,可以看出JVM内存管理的复杂性以及垃圾收集机制的重要性。了解和掌握这些知识点,对于开发高性能Java应用是非常有帮助的。在实际开发过程中,合理配置JVM参数、选择合适...

    实战JAVA虚拟机 JVM故障诊断与性能优化.rar

    《实战JAVA虚拟机 JVM故障诊断与性能优化》是一本深度探讨Java虚拟机(JVM)的专著,旨在帮助开发者解决实际工作中遇到的JVM相关问题,提升系统的性能表现。通过对JVM内部机制的深入理解,我们可以更有效地调试、...

    实战Java虚拟机——JVM故障诊断与性能优化.pdf

    1. **JVM架构解析**:书中可能详细介绍了JVM的内存模型,包括堆内存、栈内存、方法区、本地方法栈以及程序计数器等组成部分,帮助读者理解JVM如何管理和使用内存。 2. **垃圾收集机制**:JVM的垃圾收集是其性能的...

    JVM内存模型及分区 JVM内存模型及分区

    理解JVM内存模型对于优化Java程序性能至关重要,合理分配和管理内存能有效避免内存泄漏和性能瓶颈。例如,通过调整堆大小、设置合理的垃圾回收策略,可以优化应用的运行效率。此外,了解这些内存区域的工作原理也能...

    实战JAVA虚拟机 (JVM故障诊断与性能优化)【含源码】

    性能优化方面,书中涵盖了JVM的类加载机制、内存模型、线程调度等关键概念。例如,双亲委派模型是如何保证类加载的安全性和有序性的,如何利用JVM的内存配置避免OutofMemoryError,以及如何通过线程栈分析定位并发...

    Java虚拟机-jvm故障诊断与性能优化-源码

    1. **JVM内存模型** - **堆内存**:Java对象主要存储在堆中,分为新生代、老年代和永久代(或元空间)。新生代又细分为Eden和两个Survivor区,用于对象的创建和快速回收。 - **栈内存**:每个线程都有一个独立的栈...

    实战JAVA虚拟机 JVM故障诊断与性能优化带源码

    总的来说,这本书对于Java开发者来说是一份宝贵的资源,它不仅讲解了JVM的内部工作原理,还提供了实用的故障诊断工具和性能优化策略,有助于提升开发者解决复杂问题的能力。通过深入学习,读者可以更好地管理Java...

Global site tag (gtag.js) - Google Analytics