上篇文章我们介绍了JVM所管理的内存结构也就是运行时数据区(Run-Time Data Areas),现在我们将介绍JVM的内存分配与回收
静态内存分配与动态内存分配

JVM的内存分配主要分为两种:静态内存分配与动态内存分配与之对应的是基本类型内存分配与对象内存分配;
1、静态内存分配
       静态内存分配在编译时已确定好内存空间,程序载入时JVM把一次内存分配给它,此后不会再发生变化。这些内容包括:方法中的局部变量(基本数据类型)、类变量(基本数据类型)、对象的引用;对于方法中的局部变量是存储在Java栈的局部变量表中,方法执行结束栈帧出栈,局部变量也会跟着收回内存空间;而类变量是存储在方法区中的,这里的内存回收时间是不确定的。
2、动态内存分配
      Java里给对象分配内存是动态分配的,编译的时候并不能确定对象的存储空间大小,只是创建对象时才能进行内存空间分配,而内存空间的回收是在对象不再被引用时才能回收。对象是存储在堆中,只有当GC触发时才清理回收那些没有被引用的对象的内存空间;
如下面代码段;
    public class Test {
      byte[] bytes=new byte[1024*1024*5];
      long a=1000;
      public static void main(String[] args){
        long b=2;
        byte[] base=new byte[1024*1024*1];
        Test t=new Test();
      }
    }
    bytes:是数组内存分配在堆中的,但引用存储才方法区中,JVM将使用动态内存分配,编译时无法确定存储空间只有当创建test对象时才为bytes分配存储空间,只有当该对象没有被引用时才能被GC回收;
    a:是类变量,基本数据类型,当Test编译载入时就确定了存储空间,存储在方法区中;
    b:是方法中的基本数据类型局部变量只有执行该方法时才在栈帧的局部变量表中分配存储空间方法执行完成后就释放该栈帧,也回收局部变量表中的存储空间;
    base:局部变量,只有执行到该语句时才在堆中为它分配存储空间,引用存储在栈帧局部变量表中没有被引用时才能被GC回收;
    t:对象与数组一样在堆中分配存储空间,但对象引用存储在栈帧局部变量表中,对象没有被引用时GC才能回收存储空间;

确定是否可被回收
    接下来我们将介绍JVM的内存回收,JVM在进行垃圾回收时首先要做的是确定哪些是垃圾,然后才能回收垃圾所占用的内存空间。上面我们说过,对象要是被回收内存的前提是该对象没被活动的对象引用,那JVM是怎么知道一个对象是否被引用的呢。
一般用于确定对象是否被引用的算法有两种:引用计数算法、根搜索算法;
    引用计数算法(Reference Counting):在对象中添加个引用计数器,当有引用时对象计数器加一,引用消失时,计数器减一,只要引用计数器为0时该对象就是没有被引用的,比少编程语言使用该算法,如:python等。
    根搜索算法(GC Roots Tracing):Java、C#等使用该算法判断对象是否存活,该算法从一系列为“GC Roots”的对象为起点,从这些节点开始搜索,走过的路径为引用链(Reference Chain),当对象到GC Roots无任何引用链时,此对象就是不可用的,此不可用的对象将作为回收的对象。


               1、2、3为活动对象,三个对象到GC Roots均有引用链
               4、5 为死对象,对象到GC Roots不可达

Java中,可用于作为GC Roots的对象有:
         虚拟机栈的栈帧中局部变量表中引用的对象
         本地方法栈中的引用对象
         方法区中常量引用的对象
         方法区的中的类静态属性引用的对象
         类的Class对象的引用

垃圾收集算法
    1、 标记-清除算法(Mark-Sweep),算法分为了标记、清除两个阶段,他根据我们前面所讲的方法判断对象是否可被回收,如可回收则标记起来,待标记完所有对象后统一进行回收;
    2、 复制算法(Copying)复制收集算法把内存分为两块容量相同的空间,每次只使用一快,当一快用完时就将还存活的对象复制到另一块中,然后把原来使用过的内存空间进行回收。
    3、 标记-整理算法(Mark-Compact)该算法与标记清除算法一样首先对要清理的对象进行标记,不同的是,接下来他将存活的对象往一端移动,然后回收该端边界以外的内存空间。
    4、 分代收集算法(Generational Collection),现在不少虚拟机采用该算法,如:HotSpot,该算法把对象按不同的存活周期将内存瓜分为几个区域。如:HotSpot把堆分为新生代与老年代,然后根据各个区域的特点采用比较适合的收集算法。一般新生代对象生命周期比较短,所以采用复制算法;而老年代对象生命周期较长,所以比较适合采用标记-清理、标记-整理算法来回收。

文章首发地址:Solinx

http://www.solinx.co/archives/45

JVM探索之——内存管理(二)的更多相关文章

  1. JVM探索之——内存管理(一)

    本系列的第一篇文章,预计本系列最后面会有两三个案例. Java与C.C++不一样Java不需要Coder进行手动内存管理,而这一切都交给JVM进行自动内存管理,这从某种程度上来说也减轻了我们Coder ...

  2. JVM探索之内存管理(三)

    上节我们介绍了JVM垃圾回收的原则,还有几个垃圾收集算法:标记-清除算法.复制算法.标记整理算法.分代收集算法:现在将要说HotSpt的垃圾收集器,这小节将只是理论. Java虚拟机规范对垃圾收集器的 ...

  3. JVM内存管理(二)

    JVM内存管理          JVM在执行java程序的过程中,会把内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖 ...

  4. jvm大局观之内存管理篇(二):当java中new一个对象,背后发生了什么

    https://zhuanlan.zhihu.com/p/257863129?utm_source=ZHShareTargetIDMore 番茄番茄我是西瓜 那是我日夜思念深深爱着的人啊~ 已关注   ...

  5. JVM介绍&自动内存管理机制

    1.介绍JVM(Java Virtual Machine,Java虚拟机) JVM是Java Virtual Machine的缩写,通常成为java虚拟机,作为Java可以进行一次编写,到处执行(Wr ...

  6. OC的内存管理(二)ARC

    指针: 指向内存的地址指针变量 存放地址的变量指针变量值 变量中存放的值(地址值)指针变量指向的内存单元值 内存地址指向的值1):强指针:默认的情况下,所有的指针都是强指针,关键字strong ):弱 ...

  7. Linux内存描述之内存节点node--Linux内存管理(二)

    1 内存节点node 1.1 为什么要用node来描述内存 这点前面是说的很明白了, NUMA结构下, 每个处理器CPU与一个本地内存直接相连, 而不同处理器之前则通过总线进行进一步的连接, 因此相对 ...

  8. PHP内核探索:内存管理开篇

    内存是计算机非常关键的部件之一,是暂时存储程序以及数据的空间,CPU只有有限的寄存器可以用于存储计算数据,而大部分的数据都是存储在内存中的,程序运行都是在内存中进行的.和CPU计算能力一样, 内存也是 ...

  9. Linux内存描述之内存节点node–Linux内存管理(二)

    日期 内核版本 架构 作者 GitHub CSDN 2016-06-14 Linux-4.7 X86 & arm gatieme LinuxDeviceDrivers Linux内存管理 #1 ...

随机推荐

  1. Swagger接入

    一 简介 Swagger是一个开源项目,用于描述和生成RestAPi的文档.可以帮助开发人员快速了解web服务的功能. 二  接入Swagger流程 1.在所在Module的pom.xml中,添加Sw ...

  2. node.js如何处理请求的路由

    var http = require( 'http' ) var handlePaths = [] /** * 初始化路由配置数组 */ function initRotute() { handleP ...

  3. SQL Server 事务

    from :http://www.cnblogs.com/kissdodog/p/3169788.html 事务全部是关于原子性的.原子性的概念是指可以把一些事情当做一个单元来看待.从数据库的角度看, ...

  4. SQLServer2008部署镜像

    SQL Server 2008 R2数据库镜像部署 概述 “数据库镜像”是一种针对数据库高可用性的基于软件的解决方案.其维护着一个数据库的两个相同的副本,这两个副本分别放置在不同的SQL Server ...

  5. linux常用命令之文件管理

    LS ls:list directory contents 默认情况 默认情况下显示的是mtime 选项 -a 列出全部文件及目录包括隐藏的 -l 列出详细信息,包括文件类型.权限.节点.owner. ...

  6. iOS安全笔记

    这一篇文章, 加上里面链接的几篇文章(一个百度的, 两个阮一峰的), 全看完应该了解得差不多了 如何打造一个安全的App?这是每一个移动开发者必须面对的问题.在移动App开发领域,开发工程师对于安全方 ...

  7. toastr 自定义提示

    在线实例 实例演示 使用方法 <button type="button" class="btn btn-primary" id="showtoa ...

  8. SlidesJS - 老牌的响应式 jQuery 幻灯片插件

    SlidesJS 是一款老牌的 jQuery 幻灯片插件,经过多年的发展,已经成为一款功能齐全,设计精巧的幻灯片插件.支持循环.自动播放功能和淡入淡出过渡效果,并且能够自动生成分页,可以帮助开发者制作 ...

  9. Request.MapPath和ServerMapPath

    一.路径 / 念 反斜杠,/ 是超文本协议的路径分隔符号,所有的网站在浏览器中显示的路径分隔都是以"/"表示.它一般代表虚拟路径. \ 念 斜杠,在普通程序代码中则以"\ ...

  10. 删除oracle表报ORA-24005错误

    请先执行:alter   session   set   events'10851   trace   name   context   forever,level   1'; 然后再删除表.