`
zhaohongwei1982
  • 浏览: 7966 次
  • 性别: Icon_minigender_1
  • 来自: 天上人间
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

jvm内存管理

    博客分类:
  • java
阅读更多

      java不像C++那样需要显示的分配和释放内存,对java程序员是一种解放,很大程度降低了编程的难度,因为内存管理的工作都交由jvm来自动进行。但是jvm自动管理内存也是一把双刃剑,会造成宝贵的内存资源浪费,搞不好还会造成内存泄露。所以,最为一名java程序员需要对jvm管理内存的机制进行深入了解,才能更好的利用内存。

 

内存空间的划分

Sun JDK也是遵照jvm规范,将内存空间划分为方法区、堆、本地方法栈、pc寄存器、jvm方法栈。如下图:

 

 
 

方法区

      方法区存放了要加载的类的信息、类中的静态变量、类中定义为final类型的常量、类中的field信息、类中的方法信息。方法区是全局共享的,特定条件下会进行GC,当方法区要使用的内存大于运行大小时会抛OOM异常。

      Sun JDK中这块内存对应Permanent Generation,也叫持久代,默认最小16M,最大64M,通过-XX:PermSize和-XX:MaxPermSize参数指定持久代的最小和最大值。

      堆用于存储对象实例及数组值,可以认为java中所有通过new操作符创建的对象都放在堆中,堆中对象由GC进行回收。这块内存大小可以通过两个参数进行指定:-Xms和-Xmx。

-Xms表示jvm启动时申请的最小heap内存,默认为物理内存的1/64但小于1G。

-Xmx表示jvm可申请的最大heap内存,默认为物理内存的1/4但小于1G。

默认当空闲堆内存小于40%是,jvm会增大heap到-Xmx指定的大小,这个比例可以通过参数-XX:MinHeapFreeRatio=来指定;默认当空闲堆内存大于70%时,jvm会减小heap到-Xms指定的大小,这个比例可以通过参数-XX:MaxHeapFreeRatio=来指定。建议将-Xms和-Xmx设置为相同的值,以避免频繁调整jvm堆大小。

 

由于不同对象在内存中存活的时间不同,有的很快就可以回收,有的可能生命周期贯穿整个jvm的生命周期,所以在Sun JDK从1.2开始就对堆内存进行分代管理。如下图:



 

 

新生代(New Generation)

大多数情况下java程序中创建的对象都是从新生代分配内存,新生代有两部分组成:Eden space和两块大小相等的Survivor space(S0和S1)。

可以通过参数-Xmn来指定新生代的大小,通过-XX:SurvivorRatio来指定Eden space和Survivor space的大小。

旧生代(Old Generation或 Tenuring Generation)

旧生代主要用于存放经过多次垃圾回收仍然存活的对象,但在某些情况下第一次创建对象就直接在旧生代分配内存,比如:大对象,可以通过参数-XX:PretenureSizeThreshold=(单位为字节,默认为0)指定当对象大小超过多大时直接放入旧生代;大数组对象,且数组中无外部引用对象。

本地方法栈

 本地方法栈用于支持native方法的执行,Sun JDK中的实现是本地方法栈和jvm方法栈是同一个。

PC寄存器和jvm方法栈

每个线程都有自己的PC寄存器和jvm方法栈,pc寄存器占用的可能是cpu寄存器或操作系统内存,jvm方法栈占用的为操作系统内存,jvm方法栈为线程私有,线程运行完毕时其对应栈帧所占用的内存全部自动释放掉。

Sun JDK中通过参数-Xss来指定jvm方法栈大小,当jvm方法栈空间不足时抛StackOverflowError.

 

 

内存的分配

 jvm堆是所有线程共享的,因此在堆上分配内存需要加锁,从而导致创建对象开销较大。当堆空间不足时会触发GC,如果GC后堆空间仍然不足会跑OutOfMemory异常。

Sun JDK为提升内存分配效率,在新生代的Eden space为每个线程创建一个叫做TLAB(Thread Local Allocation Buffer)的区域,当在线程中创建对象时jvm会尽量在TLAB中分配内存,这时就不需要加锁,节省了创建对象的开销。

还有一种基于逃逸分析的方法,jvm会在栈上直接分配内存,线程结束时自动就释放掉。

 

内存的回收

收集器算法

jvm通过GC来回收内存,GC就是通过分析程序中不再被使用的对象,把这些对象所占内存收回,GC通常采用收集器方式,主要有引用计数收集器和跟踪收集器。

引用计数收集器

引用计数器采用分散的管理方式,通过记录对象的引用次数进行判断对象是否可能回收,当对象的引用计数为0时GC就可以回收该对象。但是引用计数器方式有他的缺点:每次对对象的赋值操作都会伴随有引用计数的增减,带来一定的额外消耗;对象间出现循环引用时会失效。所以Sun JDK实现中没有采用引用计数器的方式。

跟踪收集器

跟踪收集器采用集中式的管理方式,全局记录数据的引用状态,执行GC时从根集合进行对象扫描,可能会造成应用程序暂停,线程阻塞。主要有复制(copying),标记-清除(mark-sweep),标记-压缩(mark-compact)三种算法实现。

Sun JDK中可用的GC算法

新生代GC(Minor GC)

新生代中对象通常存活时间短,对象少,所以选择copying算法实现新生代的GC。GC过程中复制对象时需要一块未使用的内存区来存放存活的对象,这也是新生代划分为Eden,S0,S1的原因。Eden存放刚创建的对象,S0或S1的其中一块用作Minor GC的复制目标空间,另一块被清空;下一次Minor GC时S0和S1交换角色。

串行GC

在整个扫描和复制过程采用单线程的方式来进行,适用于单CPU、新生代空间较小及对暂停时间要求不是非常高的应用上,是client级别默认的GC方式,可以通过-XX:+UseSerialGC来强制指定。 

并行回收GC

在整个扫描和复制过程采用多线程的方式来进行,适用于多CPU、对暂停时间要求较短的应用上,是server级别默认采用的GC方式,可用-XX:+UseParallelGC来强制指定,用-XX:ParallelGCThreads=4来指定线程数。

并行GC

与旧生代的并发GC配合使用。

旧生代GC

 旧生代与新生代不同,对象存活的时间比较长,比较稳定,因此采用标记(Mark)算法来进行回收,所谓标记就是扫描出存活的对象,然后再进行回收未被标记的对象,回收后对用空出的空间要么进行合并,要么标记出来便于下次进行分配,总之就是要减少内存碎片带来的效率损耗。在执行机制上JVM提供了串行GCSerial MSC)、并行GCparallel MSC)和并发GCCMS)。

 

最后

创建对象(尤其是大对象)可能会触发GC,所以需要频繁创建的对象可以考虑通过池来解决;

注意对象的作用域,不用的及时显示设置为null,GC就可以收掉;

通过设置jvm参数对应用调优,有很多工具来帮助分析jvm内存使用清空,茹jconsole,jstat,jmap等等,但要具体系统具体分析,总之尽量减少GC,尤其是Full GC(会导致线程阻塞)。

  • 大小: 34.8 KB
  • 大小: 18.8 KB
分享到:
评论

相关推荐

    JVM 内存管理之道

    JVM 内存管理之道 JVM垃圾回收机制 JVM GC组合 JVM 内存监控工具

    JVM内存管理白皮书

    在这份由Sun Microsystems公司出版的《JVM内存管理白皮书》中,我们可以找到关于Java虚拟机(JVM)内存管理的详细介绍和深入分析。这份文档对于想要深入了解JVM工作原理的读者来说是一份宝贵的学习资料。在这份...

    jvm内存管理,pdf

    ### JVM内存管理详解 #### 一、引言 在探讨JVM内存管理之前,我们先来看一下为何要深入了解这一主题。对于深入掌握Java的人来说,内存管理是不可或缺的一部分。随着技术的发展,内存管理变得越来越自动化,但这也...

    JVM-内存管理 2012-12.pdf

    JVM内存管理是Java平台的一个重要特性,其内存空间的分配和回收机制对Java应用程序的性能和稳定性有着至关重要的影响。 首先,JVM内存管理涉及的内存空间主要分为方法区(Method Area)、堆(Heap)、本地方法栈...

    JVM内存管理及调优

    **JVM内存管理及调优** Java虚拟机(JVM)是Java程序运行的基础,它为Java应用程序提供了运行环境。JVM内存管理是优化Java应用性能的关键环节,涉及到内存分配、垃圾回收以及内存溢出等问题。毕玄,一位在淘宝有着...

    JVM内存管理学习笔记

    《JVM内存管理学习笔记》 在Java世界中,JVM(Java Virtual Machine)是运行所有Java应用程序的核心。深入理解JVM内存管理对于优化程序性能、预防和解决内存泄漏问题至关重要。本文将从JVM内存模型、内存区域划分、...

    JVM内存管理

    JVM内存管理

    JVM内存管理和JVM垃圾回收

    理解JVM内存管理和垃圾回收机制对于优化Java应用的性能至关重要。开发者可以根据应用的需求和特点,通过调整JVM参数来选择合适的内存配置和垃圾回收策略。同时,使用如JVisualVM等工具进行实时监控和分析,可以帮助...

    JVM内存管理、调优与监控考据

    总的来说,JVM内存管理、调优与监控是一项综合性的技术工作,需要对JVM内部机制有深入理解,并结合具体应用场景进行细致的分析和实践。由于JVM的实现可能存在差异,且规范与实现之间存在一定的不一致性,因此,进行...

    JVM内存管理和垃圾回收

    理解JVM内存管理和垃圾回收机制对于优化Java应用程序性能至关重要,开发者可以通过调整JVM参数来定制适合应用需求的内存配置和垃圾回收策略。例如,设置新生代和老年代的大小、选择合适的垃圾回收器、设定最大暂停...

    JVM内存管理白皮书[借鉴].pdf

    在《JVM内存管理白皮书》中,深入探讨了JVM如何处理内存分配、垃圾收集以及各种收集器的工作原理。以下是对该白皮书部分内容的详细解读: 1. 显式与自动内存管理: 在传统的C++等语言中,程序员需要手动进行内存...

    从JVM内存管理的角度谈谈静态方法和静态属性

    理解JVM内存管理和静态成员的工作原理对于优化Java程序的性能至关重要。合理的对象创建、内存使用以及静态成员的恰当运用,都可以帮助提升程序效率并降低内存消耗。在编写代码时,应根据实际需求选择静态或非静态...

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

    JVM 内存管理面试常见问题全解 JVM 内存管理是 Java 程序员必须掌握的重要知识点,本文将对 JVM 内存管理的面试常见问题进行全解。 一、什么是 JVM Java Virtual Machine(Java 虚拟机)是 Java 程序实现跨平台的...

    JVM内存管理和垃圾回收.pdf

    Java虚拟机(JVM)内存管理和垃圾回收是Java编程中至关重要的概念,它涉及到...总之,JVM内存管理和垃圾回收是优化Java应用性能的关键。了解这些概念并正确配置JVM参数,可以帮助开发者创建更高效、更稳定的软件系统。

    JVM内存管理知识思维导图.png

    JVM内存管理知识思维导图.png

    JVM内存管理-GC模型-编写GC友好的代码.pdf

    ### JVM内存管理与GC模型详解 #### 一、引言 在现代软件开发中,Java虚拟机(JVM)作为一种广泛使用的平台,其内部机制尤其是内存管理和垃圾收集(GC)模型,对提升程序性能和稳定性至关重要。本文将深入探讨Sun ...

    JVM内存管理和垃圾回收参考.pdf

    Java虚拟机(JVM)内存管理和...总结来说,JVM内存管理和垃圾回收是一个复杂而精细的过程,涉及多种策略和算法,旨在高效利用内存,减少应用暂停时间,并防止内存泄漏。理解和掌握这些原理对优化Java应用性能至关重要。

Global site tag (gtag.js) - Google Analytics