搬以前写的博客【2014-12-30 15:07】

以前很少关注内存的问题,基本没有关注,这方面的小白,原因在于自己都是写的自我娱乐的小程序,不关注性能,不是提供服务。而企业级别的应用在程序稳健性方面的要求大大提高,因此要考虑更多的问题。对于大公司来说,为了应对各种情况,服务器资源肯定充足,但是由于应用很多,那么我们要尽可能的节省资源,对于Java程序,内存资源相当宝贵,那么理解java里面怎么做垃圾回收,是很重要的。

我阅读的参考主要是两个内容[1,2],但还没有做具体的实践,也没有切身体会,只能纸上谈兵了。
那么首先要介绍Java里面的内存分配,Java的内存是交由JVM来管理的,大致分为:栈 和 堆 两个部分。
栈,以前在数据结构里学到,是一种先入后出(FILO)的结构,栈里的每一个元素称为一个帧,在Java中,每有一个新的方法被调用,就会在栈里面开辟一段新的空间,里面保存该方法的参数,局部变量、返回地址,引用次数等等。我们知道,参数和局部变量的类型只能是 基本类型 或者 对象的引用。那么栈有一个优点就是,当被调用方法结束时,栈里面的相应帧被删除,这样,方法的参数局部变量也随之清空。
另外一片区域是 堆。堆里面存的是什么?对,是对象,因为对象的大小是动态分配的,栈不能提供这功能,而堆可以。但问题也随之而来,如果一个方法结束时,对象的引用是清空了,但堆里面的对象本身内容不会被清空,只会越积越多,最后程序运行到一定时候,堆内内存溢出。因此,就需要管理堆里面的内存,而Java已经提供了垃圾回收的机制。
什么是垃圾?要回收什么?刚才就看得到,我们要回收的就是那些已经没有引用的对象,这些对象称为 不可达到。很直白,一个对象如果没有应用了,那么他就没有意义了。那么一个很简单的想法,我们为每一个对象保留一个引用计数器,如果计数器为0的时候,就回收该对象内存。这种想法思路正确,但是有两个问题,首先是效率问题,如果一旦有对象没有引用,就立刻回收该对象,那么时间效率会低。 其次如果两个对象相互应用,那么实际上他们是不可达到的,但是不会被回收。
先讨论第二个问题,我们定义 根可达,也就是如果能从栈里的对象引用出发,达到某个对象,那么称它为根可达,我们回收那些不是根可达的对象。
再就是第一个问题,Java的回收机制实际上是混合多种方法的。我们实际写程序时,会发现一个特点,对象回收时,大部分都是新构造不久的对象,那么我们根据这个特点,设计了分代回收机制。将堆内存划分为 年轻代,成熟代,永久代。分代回收机制在不同的区域使用不同的回收策略。
年轻代存放的是新构造不久的对象,采用 copy and sweep。它又分为3个区,伊甸园,from区,to区。伊甸园指的是自从上一次GC之后新构造的对象存放的区域。from区是上一次GC保留下来存活时间不长的对象。to区空白。当伊甸园内存满时,触发一次GC。此时会将from区,伊甸园区中根可达的对象复制到 to区(如果某些对象世间存活很长,会复制到成熟代),并且清空原来的伊甸园,from区。如果 to 区 满了,同样会把一部分复制到成熟代。此时原来的from区变为to区,原来的to区变为from区,交换角色。
成熟代采用的则是 mark and sweep,当成熟代满时,会扫描一次内存,并将根不可达的那些标记下来,并清除。
copy and sweep,mark and sweep的区别在于,一次清除后,前者内存连续,后者不连续。
而永久代则不会用垃圾回收。
至此,大概讲述了java的垃圾回收机制,实际上java的内存远不止堆和栈,但是涉及到垃圾回收的部分大概就是这些。以后再慢慢理解补充。
1. http://www.cnblogs.com/vamei/archive/2013/04/28/3048353.html
2. http://blog.csdn.net/turkeyzhou/article/category/751216

【Java学习笔记】Java的垃圾回收机制的更多相关文章

  1. Java学习笔记-对象与垃圾回收

    Java存在垃圾回收机制,JVM会去回收垃圾,释放资源,而不是像C++一样有程序员去完成 垃圾回收机制的特点 垃圾回收机制只负责回收堆内存中的对象,不会回收任何物理资源(例如数据库连接.网络IO等资源 ...

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

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

  3. [java学习笔记]java语言核心----面向对象之this关键字

    一.this关键字 体现:当成员变量和函数的局部变量重名时,可以使用this关键字来区别:在构造函数中调用其它构造函数 原理:         代表的是当前对象.         this就是所在函数 ...

  4. [java学习笔记]java语言核心----面向对象之构造函数

    1.构造函数概念 特点: 函数名与类名相同 不用定义返回值类型 没有具体的返回值 作用:                给对象进行初始化 注意: 默认构造函数 多个构造函数是以重载出现的 一个类中如果 ...

  5. [Java] 理解JVM之三:垃圾回收机制

    JVM内存中的各个区域都会回收吗? 首先我们知道 Java 栈和本地方法栈在方法执行完成后对应的栈帧就立刻出栈销毁,两者的回收率可以认为是100%:Java 堆中的对象在没有被引用后,即使用完成后会被 ...

  6. Java基础知识总结之垃圾回收机制

    垃圾回收机制 Java垃圾回收机制是Java语言的重要功能之一.当程序创建对象,数组等引用类型对象时,系统会自动在内存区为之分配一块内存,对象就保存在这块内存区内,当这块内存不再被任何变量引用时,这块 ...

  7. jvm学习笔记一(垃圾回收算法)

    一:垃圾回收机制的原因 java中,当没有对象引用指向原先分配给某个对象的内存时候,该内存就成为了垃圾.JVM的一个系统级线程会自动释放该内存块.垃圾回收意味着程序不再需要的对象是"无用信息 ...

  8. [java学习笔记]java语言基础概述之内存的划分&堆和栈

    1.内存的划分 1.寄存器 cpu处理 2.本地方法区 和所在系统相关 3.方法区 方法加载进内存,其实就是开辟了一块该方法的方法区 方法区中还可以有静态区,用于存放静态变量(类变量) 4.栈内存 5 ...

  9. [Java学习笔记] Java异常机制(也许是全网最独特视角)

    Java 异常机制(也许是全网最独特视角) 一.Java中的"异常"指什么 什么是异常 一句话简单理解:异常是程序运行中的一些异常或者错误. (纯字面意思) Error类 和 Ex ...

  10. Java学习笔记 -- Java定时调度工具Timer类

    1 关于 (时间宝贵的小姐姐请跳过) 本教程是基于Java定时任务调度工具详解之Timer篇的学习笔记. 什么是定时任务调度 基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务. 在Ja ...

随机推荐

  1. 笔试算法题及解答(Python)

    1.给定任意一个正整数,求比这个数大且最小的“不重复数”,“不重复数”的含义是相邻两位不相同,例如1101是重复数,而1201是不重复数 # coding:utf-8 ''' Created on 2 ...

  2. 2019牛客多校第五场F maximum clique 1 最大独立集

    题意:给你n个数,现在让你选择一个数目最大的集合,使得集合中任意两个数的二进制表示至少有两位不同,问这个集合最大是多大?并且输出具体方案.保证n个数互不相同. 思路:容易发现,如果两个数不能同时在集合 ...

  3. Git--将已有的项目添加到github(转)

    转自:https://blog.csdn.net/north1989/article/details/53471439 1. 目标: 把本地已经存在的项目,推送到github服务端,实现共享. 2. ...

  4. A new session could not be created. (Original error: Could not find a connected Android device.)

    1 终端执行adb   devices 查看知否看到设备 1 查看手机 的开发者 usb调试功能是否打卡 2 重启电脑,cmd 执行  adb devices  重新打开

  5. 力扣 ——Remove Duplicates from Sorted List II(删除排序链表中的重复元素 II)python实现

    题目描述: 中文: 给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字. 示例 1: 输入: 1->2->3->3->4->4-> ...

  6. linux-ftp install

    ftp安装 yum install vsftpd vi /etc/vsftpd/vsftpd.conf (可以先备份,但不要放在此目录下,不然启动vsftpd的时候 也会加载其备份文件,报启动错误,因 ...

  7. ubuntu Oracle SQL Developer 安装

    一. 官网下载oracle 安装包 二.下载完毕后,检查你的Ubuntu是否安装了tar和alien sudo apt-get install tar sudo apt-get install ali ...

  8. js instanceof和typeof的区别及简单用法

    js中判断一个变量的类型,通常的做法是用typeof方法,看它返回的是 什么,但是对于数组和对象它返回的都是object,ECMAScript引入了java中的instanceof 方法来弥补这一缺陷 ...

  9. PHP filter_var_array() 函数

    定义和用法 filter_var_array() 函数获取多个变量,并进行过滤. 该函数对过滤多个值很有用,无需重复调用 filter_var(). 如果成功,则以数组形式返回请求变量的值.如果失败, ...

  10. Myeclipse下使用Maven搭建spring boot2.0项目

    现在需要搭建spring boot框架,并实现一个HelloWorld的项目,让程序真正运行起来. 一.在pom.xml中引入spring-boot-start-parent,spring官方的叫st ...