前言:
       我们在运行程序时,有时会碰到内存溢出(OutOfMemoryError)的问题,为了解决这种问题,我们有必要了解JVM的内存结构和垃圾回收机制。


正文:

1.JVM堆内存结构


        JVM主要管理两种类型的内存,堆内存和非堆内存。
        “java虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此分配,堆是java虚拟机启动时创建的”,对内存就是代码可及的地方。
       “java虚拟机除堆外的内存称为非堆内存”,是java虚拟机自己内部所需的内存。

        JVM堆内存的结构如下图所示:
        
   JVM堆内存分为新域,旧域,永久域三个部分。
   我们下面通过程序申请内存的过程了解各个区域的作用:
   1.当我们在程序中通过new创建一个对象时,会为该对象在堆的新域的eden中分配一块内存(eden用来存放新生对象);
   2.执行1时,如果eden中的内存不够,JVM将试图释放eden中的不活跃对象(此时叫:minor collection),如果eden的内存仍不足以存放新创建的对象,则将eden中剩余的活跃对象转移到救助空间中;
   3.当旧域的空间足够时,救助空间的对象会被转移到旧域(所以survivor相当于eden与旧域的中间交换区);
   4.当旧域空间不够时会释放空间(此时叫:major collection)
   5.如果survivor和旧域无法存放eden复制过来的对象,导致eden无法为新对象分配内存,会报:OutOfMemoryError

2.JVM垃圾回收

     在上面的申请内存过程中已经涉及到了垃圾回收,下面在详细说一下。
     先说一下新域的垃圾回收过程:
     在新域中有两个survivor作为中转,两个survivor相对的作为from和to逻辑区域,其中from区域用来保存对象,to区域保持为空。
     当eden区域不足以支持新增对象时,会执行垃圾回收(GC),eden中的对象和from区域的对象转移到to区域,当to区域满时,一部分对象转移到old区域,即旧域。
     
GC执行结束后eden和from区域被清空,这是from区域和to区域进行交换。

   关于这里为什么JVM要用两个survivor来做中转,一说是:“对象在两个survivor之间来回移动,知道他们足够老,能够放入保存期较长的old即旧域”。
            

3.解决堆溢出问题

上面我们了解了JVM堆内存的结构和GC,当我们遇到java.lang.OutOfMemoryError: Java heap space这个异常时,可以通过重新设定参数来解决。
    JVM在启动时会自动自动设置Heap Size的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项可 进行设置。Heap size 的大小是Young Generation 和Tenured Generaion 之和。 提示:在JVM中如果98%的时间是用于GC且可用的Heap
size 不足2%的时候将抛出此异常信息。 提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。


版权声明:本文为博主原创文章,未经博主允许不得转载。

巩固java(二)----JVM堆内存结构及垃圾回收机制的更多相关文章

  1. JVM原理(Java代码编译和执行的整个过程+JVM内存管理及垃圾回收机制)

    转载注明出处: http://blog.csdn.net/cutesource/article/details/5904501 JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.e ...

  2. JVM内存管理和垃圾回收机制介绍

    http://backend.blog.163.com/blog/static/20229412620128233285220/     内存管理和垃圾回收机制是JVM最核心的两个组成部分,对其内部实 ...

  3. Java中内存泄露及垃圾回收机制

    转自:http://blog.sina.com.cn/s/blog_538b279a0100098d.html 写的相当不错滴...................... 摘  要 Java语言中,内 ...

  4. JVM内存分配与垃圾回收机制管理

    项目上线,性能优化有个重要组成就是jvm内存分配和垃圾回收机制的管理配置. 网上随便能搜到相关的具体步骤,以及内存中各种参数对应的意义,不再赘述. 干货就是直接抛出遇到的问题,以及如何解决的,再说说待 ...

  5. V8 内存管理和垃圾回收机制总结

    这篇文章主要介绍 V8 的内存管理和垃圾回收知识. V8 内存管理及垃圾回收机制浅析 由于 V8 引擎的原因,Node 在操作大内存对象时受到了一些限制,在 64 位的机器上,默认最大操作的对象大小约 ...

  6. 你还在为了JVM而烦恼么?(内存结构和垃圾回收算法)

    ​ 做JAVA也有接近2年的时间了,公司的leader说,做JAVA,三年是个坎,如果过了三年你还没有去研究JVM的话,那么你这个程序员只能是板砖的工具了.恰逢辞职,来个JVM的解析可好? JVM是J ...

  7. JVM的生命周期、体系结构、内存管理和垃圾回收机制

    一.JVM的生命周期 JVM实例:一个独立运行的java程序,是进程级别 JVM执行引擎:用户运行程序的线程,是JVM实例的一部分 JVM实例的诞生 当启动一个java程序时.一个JVM实例就诞生了, ...

  8. JVM内存管理及垃圾回收机制

    一.JVM内存组成结构 JVM栈由堆.栈.本地方法栈.方法区等部分组成,结构图如下所示:  二.JVM内存回收 Sun的JVMGenerationalCollecting(垃圾回收)原理是这样的:把对 ...

  9. java基础(一):谈谈java内存管理与垃圾回收机制

    看了很多java内存管理的文章或者博客,写的要么笼统,要么划分的不正确,且很多文章都千篇一律.例如部分地方将jvm笼统的分为堆.栈.程序计数器,这么分太过于笼统,无法清晰的阐述java的内存管理模型: ...

随机推荐

  1. kettle 的表输出 table output

    kettle的表输出: 双击后,看设置, 1,在connecttion后面,点击new里新建一个.设定各个选项值,如选择mysql类型,则配置hostname,database name,端口, 用户 ...

  2. Android实训案例(二)——Android下的CMD命令之关机重启以及重启recovery

    Android实训案例(二)--Android下的CMD命令之关机重启以及重启recovery Android刚兴起的时候,着实让一些小众软件火了一把,切水果,Tom猫,吹裙子就是其中的代表,当然还有 ...

  3. web报表工具FineReport常用函数的用法总结(数学和三角函数)

    最后一次抛砖引玉了,至此finereport所有的常见函数就分享完了,期待能对大家有些许帮助. ABS ABS(number):返回指定数字的绝对值.绝对值是指没有正负符号的数值. Number:需要 ...

  4. SharePoint JS感悟-js脚本

    最近有些迷恋js脚本,因为自己对Asp.net不够熟悉,又是Moss的一年级新生,不是对代码开发不感兴趣,面向对象自己也了解一些,代码也能大致读懂,个人觉得还是经验积累,作为代码开发人员,还是需要3- ...

  5. OS X 平台的 8 个实用终端工具

    本文由 伯乐在线 - shinancao 翻译自 mitchchn.欢迎加入iOS小组.转载请参见文章末尾处的要求. OS X 终端对外开放了许多很强大的UNIX实用工具和脚本.如果你是从Linux转 ...

  6. 和菜鸟一起学linux之initramfs方式启动

    关于initramfs initramfs在编译内核的同时被编译并与内核连接成一个文件,它被链接到地址__initramfs_start处,与内核同时被加载到ram中.initramfs被解析处理后原 ...

  7. machine learning 之 Neural Network 2

    整理自Andrew Ng的machine learning 课程 week5. 目录: Neural network and classification Cost function Backprop ...

  8. oracle索引建立和删除

    1.多列建立索引 SQL> create index dex_index2 on dex(sex,name); Index created. SQL> select object_name ...

  9. ROS:使用Qt Creator创建GUI程序(一)

    开发环境: Ubuntu14.04 ROS indigo version Qt Creator 3.0.1 based on Qt 5.2.1 步骤如下:(按照下面命令一步步来,亲测可行) (一)安装 ...

  10. Angularjs Post传值后台收不到的原因

    如果你给AngularJS的post方法的data参数创一个key-value对象,那传给后台服务的就是JSON字符串,而正常的POST解析是需要像get?后面的那种&name=value这样 ...