在上一篇中,已经介绍了内存结构是什么样的. 这篇来介绍一下 内存是怎么分配的,和怎么回收的.(基本取自《深入理解Java虚拟机》一书)

java技术体系中所提倡的自动内存管理最终可以归结为自动化的解决了两个问题--给对象分配内存以及回收分配给对象的内存.我们下面就来介绍这些是怎么自动化完成的.

下面继续提出问题:

1.怎么判断对象是否能被回收?

2.垃圾回收是怎么进行的?

3.方法区存在垃圾回收吗?

4.垃圾回收都有什么算法?

5.MinorGC,FullGC,新生代,老年代,永久代,Eden,Survivor 这些名词都是什么意思?

6.内存分配策略(规则)是什么?

下面来解决问题:

1.怎么判断对象是否能被回收?

java是采用的跟搜索算法(GC Roots Tracing)来判定对象是否存活.简单讲就是如果一个对象到 根节点之间不可达时,就可以被回收了.

那么问题来了.根节点是什么呢? 在java语言里,能做根节点的包括下面几种:

1) 虚拟机栈中的引用对象

2) 方法区中的类静态属性引用的对象

3) 方法区中的常量引用的对象

4)本地方法栈JNI(即Native方法)的引用的对象.

这里需要说明一下,上面所说的引用,都是指的强引用. 我们知道java中引用有四种.强,软,弱,虚.我们平常的引用都是指的强引用,像缓存一般使用软引用来实现.

2.垃圾回收是怎么进行的?

上面一点讲了怎么判断一个对象是否能被回收,那么是否能被回收,就一定会被回收呢? 当然不是.

首先垃圾回收行为是不确定什么时候执行的. 其次.回收一个对象,至少要经理两次标记过程:

1)判断对象是否与GC Roots之间有引用链

2)如果没有,则进行第一次标记,并按此对象是否需要执行finalize()方法进行筛选.

3)如果对象不需要执行finalize()方法,则第二次标记为可回收.此时真正可回收.

4)如果需要执行finalize()方法,则会被放在一个F-Queue队列中去执行,稍后GC将对F-Queue中的对象进行二次标记.如果成功拯救自己(譬如把自己赋值给某个引用链上的对象),则会在标记中移除. 如果没能拯救,则此时真正可回收.

另外说下.《深入理解Java虚拟机》一书建议我们忘掉 finalize()这个方法.

3.方法区存在垃圾回收吗?

方法区在HotSpot虚拟机中又名永久代, 永久代还存在或者说还需要垃圾回收吗?

这个区域是存在垃圾回收的,但是垃圾回收的效率比较低.就是说回收一次释放不了多少空间.永久代主要回收内容是 废弃常量和无用的类.

在大量使用反射,动态代理,CGLib等bytecode框架的场景,以及动态生成JSP和OSGi这类频繁自定义ClassLoader的场景都需要虚拟机具备回收无用的类的功能.以保障永久代不溢出.

4.垃圾回收都有什么算法?

常用的算法 标记-清除算法,复制算法,标记-整理算法. 分代收集算法.

前面3种算法,各有优缺点,分代收集算法其实只是把java堆分成了几块,每块使用前面算法中最适合的算法.

垃圾回收器也有很多种.具体可以看《深入理解Java虚拟机》一书

5.新生代,老年代,永久代,Eden,Survivor ,MinorGC,FullGC,这些名词都是什么意思?

让我们打开jdk/bin/jvisualvm.exe  这个工具,装上Visual GC 这个插件.打开后如下图,是我eclipse运行时的截图.

整个jvm内存情况在图中都有显示,

Perm 就是方法区,也称为永久代.

Old+Eden+S0+S1 = 堆. Eden+S0+S1 = Young

Old 就是老年代, Young就是新生代.

S0和S1中一定会有一个为空,这是因为垃圾回收算法决定的(复制算法)HotSpot默认的S0,S1与Eden的大小比例为1:8.

Eden区满后,会触发MinorGC(新生代GC),Old区满后会触发FullGC(老年代GC,Major GC). (注意不一定是存满才触发.)

新生代GC比较频繁,但是回收速度也快,老年代GC理论上不会太频繁,但是回收速度比较慢.(对应图中,GC time 21次,1.251s,全部都是Eden区发生的,OldGen区没有发生FullGC)

为什么新生代还要细分为Eden,Survivor0,Survivor1呢? 其实这都是为了配合垃圾回收算法来分的.

6.java内存分配策略是什么?

其实从上面的对堆的划分,就大概能了解到java内存是怎么分的了.

简单讲就是优先分配在Eden区, 如果经历了一些回收后,还没死掉,那么就有资格进入到Old区. 又或者有些比较大的对象,直接就分配在Old区.

上面说的是堆的内存分配, 栈的内存分配就更简单了.java栈的分配是和线程绑定在一起的,创建一个线程时,就会为这个线程创建一个栈,

从栈和堆的功能和作用来比较,堆主要用来存放对象,栈主要用来执行程序.

垃圾回收和分配的说完了, 很多细的东西都没说,因为现阶段感觉还用不到,也不容易理解.

jvm内存分配和回收策略的更多相关文章

  1. JVM 内存分配和回收策略

    对象的内存分配,主要是在java堆上分配(有可能经过JIT编译后被拆为标量类型并间接地在栈上分配),如果启动了本地线程分配缓冲,将按线程优先在TLAB上分配.少数情况下也是直接分配到老年代,分配规则不 ...

  2. A4. JVM 内存分配及回收策略

    [概述] Java 技术体系中所提倡的自动内存管理最终可以归结为自动化地解决两个问题:给对象分配内存以及回收分配给对象的内存. 对象的内存分配,往大方向讲,就是在堆上分配,对象主要分配在新生代的 Ed ...

  3. JVM——内存分配与回收策略

    1.对象优先在Eden区分配 大多数情况下,对象在新生代Eden区分配.当Eden区没有足够的空间进行分配时,虚拟机将发起一次Minor GC. 虚拟机提供了 -XX:+PrintGCDetails这 ...

  4. JVM内存分配与回收策略

    对象优先在Eden分配 大多数情况下,对象在新生代Eden区中分配. 当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC. Minor GC:新生代GC,指发生在新生代的垃圾收集动作 ...

  5. Java虚拟机垃圾回收:内存分配与回收策略 方法区垃圾回收 以及 JVM垃圾回收的调优方法

    在<Java对象在Java虚拟机中的创建过程>了解到对象创建的内存分配,在<Java内存区域 JVM运行时数据区>中了解到各数据区有些什么特点.以及相关参数的调整,在<J ...

  6. JVM垃圾回收器、内存分配与回收策略

    新生代垃圾收集器 1. Serial收集器 serial收集器即串行收集器,是一个单线程收集器. 串行收集器在进行垃圾回收时只使用一个CPU或一条收集线程去完成垃圾回收工作,并且会暂停其他的工作线程( ...

  7. JVM学习十 -(复习)内存分配与回收策略

    内存分配与回收策略 对象的内存分配,就是在堆上分配(也可能经过 JIT 编译后被拆散为标量类型并间接在栈上分配),对象主要分配在新生代的 Eden 区上,少数情况下可能直接分配在老年代,分配规则不固定 ...

  8. 最简单例子图解JVM内存分配和回收

    一.简介 JVM采用分代垃圾回收.在JVM的内存空间中把堆空间分为年老代和年轻代.将大量(据说是90%以上)创建了没多久就会消亡的对象存储在年轻代,而年老代中存放生命周期长久的实例对象.年轻代中又被分 ...

  9. 最简单例子图解JVM内存分配和回收(转)

    本文转自http://ifeve.com/a-simple-example-demo-jvm-allocation-and-gc/ http://www.idouba.net/a-simple-exa ...

随机推荐

  1. Microsoft Dynamics 365 之 味全食品 项目分享和Customer Engagement新特性分享

    味全食品 Dynamics 365项目: 在企业门户和电子商务等新营销模式频出的今天,零售业需要利用统一的管理平台管理日益庞大的客户及销售数据,整合线上线下的零售业务,从采购.仓储.生产.配送到销售. ...

  2. OCUpload的简单介绍与使用

     OCUpload (One Click Upload)译成中文就是一键上传的意思.它是JQuery的一个插件.   对于传统的文件上传,只能通过form表单,将enctype设置为multipart ...

  3. JVM和java应用服务器调优

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt413 对于调优这个事情来说,一般就是三个过程: 性能监控:问题没有发生,你并 ...

  4. 规则集之探究何时使用HashSet、LinkedHashSet以及TreeSet?

    前言 Java集合框架三种主要类型的集合:规则集(Set).线性表(List).队列(Queue).Set用来存储不可重复的元素:List用来存储有元素构成的有序的集合:而Queue则用于存储用先进先 ...

  5. wait与sellp方法区别

    Java Thread(线程)案例详解sleep和wait的区别    上次对Java Thread有了总体的概述与总结,当然大多都是理论上的,这次我将详解Thread中两个常用且容易疑惑的方法.并通 ...

  6. 非对话框程序创建组合框Groupbox

    对话框程序中的控件,例如button.groupbox之类,是直接放上去的.当然,除groupbox以外,在MFC中其他控件都有相对应的类,以支持程序员在非对话框程序中动态创建控件.而唯独好像没有gr ...

  7. java继承中的初始化顺序

    初始化顺序:父类的静态变量-->父类的静态代码块-->子类的静态变量-->子类的静态代码快-->父类的非静态变量(父类的非静态代码块)-->父类的构造函数-->子类 ...

  8. 201521123012 《Java程序设计》第三周学习总结

    一.本章学习总结 1.面对对象:(1)类 <1>属性 [1]外部类 [2]内部类 <2>方法 [1]j静态 [2]非静态 (2)对象 <1>创建对象 <2&g ...

  9. Java课程设计-定时器

    Java课程设计--定时器 1.团队课程设计博客链接 团队博客地址 2.个人负责模块或任务说明 框架构建 时间设置面板,倒计时面板 按钮设置 3.自己的代码提交记录截图 4.自己负责模块或任务详细说明 ...

  10. 创建maven项目pom.xml第一行报错

    之前也创建过几次maven项目,也是第一行报错,之前直接是右键项目强制更新maven好像就解决了,这次遇见这个问题使用这个方法好像不起作用了,给的一堆英文报错又看不懂,幸好在网上看见路人甲大神提示,根 ...