文档章节

jvm的内存回收和垃圾回收器

qingfeng哥
 qingfeng哥
发布于 2014/06/05 11:53
字数 2065
阅读 405
收藏 9
点赞 0
评论 1

jvm的内存回收和垃圾收集器

1、为什么要垃圾回收器

内存很宝贵,有限

内存泄露:该释放的内存没有而且永远没机会被释放,导致内存耗尽

内存溢出:分配不到内存了

C++中内存分配和释放完全自主,但智者千虑必有一种内存泄露的可能
要是有自动的、动态的内存分配的语言就好了,
既然能自动分配内存,那就必须得有配套的能自动回收(释放)这些内存 的机制

早在java之前就有语言能自动分配内存和自动回收内存(如Lisp),相比内存自动分配,内存自动回收更为重要和关键,因为内存是很宝贵的有限资源,这是个很高深的研究课题,主要有三个疑问:
    哪些内存需要回收           什么时候回收(释放)             怎么回收 

这些需要释放回收的内存也换个叫法就是 内存垃圾
于是解答上述问题就产生了各式垃圾回收器garbage collect-GC

jvm采用自动内存管理,并屏蔽指针这个反人类的东西,让很多人喜欢上java

2、了解jvm的内存布局

线程私有:jvm栈stack(该栈中push和pop的是带有复杂数据的栈帧)、
              pc计数器(指明正在执行哪条指令了)、
              本地方法栈
              这三个区的内存 随着线程的生灭而分配和释放,
              他们
需要的内存大小在类结构确定后、编译期就可以基本确定,gc基本不管这块

线程共享:堆heap和方法区method area(含有运行时常量区)
              堆中有多少对象非得跑起来才能确定的
              方法区中的类结构信息等数据是动态加载进来的
              都是不确定的内存分配,这两块才是GC的主战场

有了内存布局的宏观认识,我们需要知道

3、怎么限制各个区的大小

即jvm运行参数,以下参数是hotspot的参数,和怎样人为来产生溢出

1、heap内存大小:-Xms20M -Xmx20M -XX:+HeapDumpOnOutOfMemoryError
                          最小        最大                oom时dump溢出时内存堆转储快照

溢出方法:不断的生成对象的实例,且不置为null

2、方法区内存大小:-XX:PermSize=20M -XX:MaxPermSize=30M

溢出方法:不断的通过反射生成新的类

3、jvm栈和本地方法栈的大小:-Xss30M -Xoss10M

溢出方法:方法递归不返回,大量线程

4、直接内存大小:-XX:MaxDirectMemorySize=20M  如果没设置的话则默认与heap堆的最大值一样(-Xmx)

溢出方法:反射获取Unsafe类的实例,然后不停的分配内存allocateMemory()

好了,针对堆和方法区,回到垃圾回收器要解决的三个问题:

4、哪些内存需要回收---对象的死活

经典引用计数法:给对象配个引用计数器,每次引用就+1,引用失效时-1 计数为0时,表明对象不再被使用
jvm没有采用引用计数器算法,因为 有对象间互相循环引用导致无法释放的问题(php、python)

jvm采用根搜索算法-对象引用遍历法           GC Roots Tracing

基本思路:采用图论知识
从一系列名为 GC Roots的对象节点出发,向下搜索,搜索走过的路径为引用链,如果一个对象和根root之间没有任何引用链可通(不可达),则认为该对象没有用了,可以死去,被标记为可回收对象

可以作为GC Roots的对象:
    栈帧中的引用的对象
    方法区中:类静态属性引用的对象、常量引用的对象
   本地方法栈中:JNI的引用的对象

?怎么回收

5、垃圾回收算法

明确 所有垃圾回收时刻都会发生  全停顿 stop the world, 应该尽量减短这个时间

产生了那么多死对象,得想办法回收他们,再入轮回。怎么个做法?基本的思路有四种:

1、标记-清理(mark-sweep)算法:两阶段,第一遍扫描标记哪些对象已死,第二遍扫描清除标死的对象

缺点:两次遍历效率不高,清除后内存产生不连续的碎片

2、复制算法copying:将内存均分,每次在其中一块分配对象,快用完时将还活着的对象都复制到 另一块上,清空已使用的那块即可。代价是内存减半,一点优化是不均分

3、标记-整理(mark-compact)算法,这是标记-清理法的改进,一遍标记并将活的对象移到内存区的一端,然后清理边界外的死对象即可


GC假设

大多数对象会很快变得不可达
只有很少的由老对象(创建时间较长的对象)指向新生对象的引用


由上述对象死活判断依据、GC假设、加上统计数据的发现,可以将对象分为不同的generation

6、JVM分代内存回收

回收之前先了解内存的分配规则,之前我去了解了下Node.js的v8 js引擎的垃圾回收机制 发现这些虚拟机都采用相类似的方法和算法哦

统计知识的应用 
按对象存活时间将对象分配到不同的内存区域,这些区域叫不同的分代 
垃圾回收针对分代对象的特征采用适宜的算法进行回收

将内存再次分区,根据对象存活时间长短将其分配到不同的区域(分代)上,一般分代回收法将内存分成三代:
新生代Eden Gen:该内存区中的对象存活时间短,很快不可达,对象一般也比较小
老生代Old Gen:该内存区中主要是老对象(经过几次回收后还可达的对象)、大对象,占用空间比新生代多
永生代:方法区

内存分配规则及gc算法:
1、新对象一般在新生代Eden中分配,Eden区没足够内存时触发新生代的一次Minor GC,Eden中对象很快死去,基本采用的是 复制算法copying:将内存均分,每次在其中一块分配对象,快用完时将还活着的对象都复制到 另一块上,清空已使用的那块即可。代价是内存减半,一点优化是不均分,而分为一块较大的Eden区和两块较小的survivor区,因为存活的对象不多。每次使用一块survivor和eden,gc时将其中的或对象都拷贝到未使用的那个survivor中,如果那个没使用的survivor空间不够则直接担保分配到 老生代,如果老生代都不够则进行老生代的gc(full Gc)。


2、大对象(很长的字符串、数组等)直接在老生代分配
分代转换:新生代中的对象经过几次gc后仍然存在,达到-XX:MaxTenuringThreshold配置的年龄值(次数)时,这些对象 晋升(转移)到老生代;
分配担保:minor gc会检测之前每次回收晋升到老生代的对象容量的平均值作为经验值,与老生代的剩余空间作比较,如果大于,则直接对老生代进行major gc(Full gc),如果小于,且存活的对象大于survivor空间,则该对象也转移到老生代
老生代存活的对象多且大,一般采用标记清理或标记-整理方法来gc

有了以上内存区的分代和几种基本gc算法,产生了多种具体的垃圾收集器

具体实现

7、JDK的垃圾收集器

JDK7一共有5种GC类型:

参考吧:http://www.importnew.com/1993.html

  1. Serial GC
  2. Parallel GC
  3. Parallel Old GC (Parallel Compacting GC)
  4. Concurrent Mark & Sweep GC  (or “CMS”)
  5. Garbage First (G1) GC

© 著作权归作者所有

共有 人打赏支持
qingfeng哥

qingfeng哥

粉丝 44
博文 122
码字总数 63706
作品 0
湛江
技术主管
加载中

评论(1)

jdk2010
jdk2010
mark
《成神之路-基础篇》JVM——垃圾回收(已完结)

Java内存模型,Java内存管理,Java堆和栈,垃圾回收 本文是[《成神之路系列文章》][1]的第一篇,主要是关于JVM的一些介绍。 持续更新中 Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收 ...

⋅ 05/05 ⋅ 0

热修复与插件化基础——Java与Android虚拟机

一、Java虚拟机(JVM) 1、JVM整体结构 使用javac将java文件编译成class文件。 类加载器(ClassLoader)将class字节码加载进JVM对应的内存中。 JVM将内存分配给方法区、堆区、栈区、本地方式...

CSDN_LQR ⋅ 05/13 ⋅ 0

聊聊JAVA虚拟机中的垃圾收集器

前言 JAVA虚拟机的垃圾收集器是虚拟机内存的清道夫,它的存在让JAVA开发人员能将更多精力投入到业务研发上。了解垃圾收集器,并利用好这个工具,能更好的保障服务稳定性。这篇文章通过分析J...

lilugoodjob ⋅ 05/13 ⋅ 0

面试中关于Java虚拟机(jvm)的问题看这篇就够了

最近看书的过程中整理了一些面试题,面试题以及答案都在我的文章中有所提到,希望你能在以问题为导向的过程中掌握虚拟机的核心知识。面试毕竟是面试,核心知识我们还是要掌握的,加油~~~ 下面...

snailclimb ⋅ 05/12 ⋅ 0

一篇简单易懂的原理文章,让你把JVM玩弄与手掌之中

jvm原理 Java虚拟机是整个java平台的基石,是java技术实现硬件无关和操作系统无关的关键环节,是java语言生成极小体积的编译代码的运行平台,是保护用户机器免受恶意代码侵袭的保护屏障。JVM...

烂猪皮 ⋅ 05/08 ⋅ 0

android-------- 强引用、软引用、弱引用、虚引用使用

在Java中,虽然不需要程序员手动去管理对象的生命周期,但是如果希望某些对象具备一定的生命周期的话(比如内存不足时JVM就会自动回收某些对象从而避免OutOfMemory的错误)就需要用到软引用和...

切切歆语 ⋅ 04/19 ⋅ 0

JAVA虚拟机 JVM 详细分析 原理和优化(个人经验+网络搜集整理学习)

JVM是java实现跨平台的主要依赖就不具体解释它是什么了 ,简单说就是把java的代码转化为操作系统能识别的命令去执行,下面直接讲一下它的组成 1.ClassLoader(类加载器) 加载Class 文件到内...

小海bug ⋅ 06/14 ⋅ 0

JVM自动内存管理机制—读这篇就够了

之前看过JVM的相关知识,当时没有留下任何学习成果物,有些遗憾。这次重新复习了下,并通过博客来做下笔记(只能记录一部分,因为写博客真的很花时间),也给其他同行一些知识分享。 Java自动内...

java高级架构牛人 ⋅ 06/13 ⋅ 0

培训云计算学校,虚拟机基本结构讲解

我们要对JVM虚拟机的结构有一个感性的认知。毕竟我们不是编程人员,认知程度达不到那么深入。一个运行时的Java虚拟机实例的天职是:负责运行一个java程序。当启动一个Java程序时,一个虚拟机...

长沙千锋 ⋅ 05/17 ⋅ 0

Java 面试知识点解析(三)——JVM篇

前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大部...

我没有三颗心脏 ⋅ 05/16 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

RabbitMQ学习以及与Spring的集成(三)

本文介绍RabbitMQ与Spring的简单集成以及消息的发送和接收。 在RabbitMQ的Spring配置文件中,首先需要增加命名空间。 xmlns:rabbit="http://www.springframework.org/schema/rabbit" 其次是模...

onedotdot ⋅ 12分钟前 ⋅ 0

JAVA实现仿微信红包分配规则

最近过年发红包拜年成为一种新的潮流,作为程序猿对算法的好奇远远要大于对红包的好奇,这里介绍一种自己想到的一种随机红包分配策略,还请大家多多指教。 算法介绍 一、红包金额限制 对于微...

楠木楠 ⋅ 24分钟前 ⋅ 0

Python 数电表格格式化 xlutils xlwt xlrd的使用

需要安装 xlutils xlwt xlrd 格式化前 格式化后 代码 先copy读取的表格,然后按照一定的规则修改,将昵称中的学号提取出来替换昵称即可 from xlrd import open_workbookfrom xlutils.copy ...

阿豪boy ⋅ 53分钟前 ⋅ 0

面试题:使用rand5()生成rand7()

前言 读研究生这3 年,思维与本科相比变化挺大的,这几年除了看论文、设计方案,更重要的是学会注重先思考、再实现,感觉更加成熟吧,不再像个小P孩,人年轻时总会心高气傲。有1 道面试题:给...

初雪之音 ⋅ 53分钟前 ⋅ 0

Docker Toolbox Looks like something went wrong

Docker Toolbox 重新安装后提示错误:Looks like something went wrong in step ´Checking if machine default exists´ 控制面板-->程序与应用-->启用或关闭windows功能:找到Hyper-V,如果处......

随你疯 ⋅ 今天 ⋅ 0

Guacamole 远程桌面

本文将Apache的guacamole服务的部署和应用,http://guacamole.apache.org/doc/gug/ 该链接下有全部相关知识的英文文档,如果水平ok,可以去这里仔细查看。 一、简介 Apache Guacamole 是无客...

千里明月 ⋅ 今天 ⋅ 0

nagios 安装

Nagios简介:监控网络并排除网络故障的工具:nagios,Ntop,OpenVAS,OCS,OSSIM等开源监控工具。 可以实现对网络上的服务器进行全面的监控,包括服务(apache、mysql、ntp、ftp、disk、qmail和h...

寰宇01 ⋅ 今天 ⋅ 0

AngularDart注意事项

默认情况下创建Dart项目应出现以下列表: 有时会因为不知明的原因导致列表项缺失: 此时可以通过以下步骤解决: 1.创建项目涉及到的包:stagehand 2.执行pub global activate stagehand或pub...

scooplol ⋅ 今天 ⋅ 0

Java Web如何操作Cookie的添加修改和删除

创建Cookie对象 Cookie cookie = new Cookie("id", "1"); 修改Cookie值 cookie.setValue("2"); 设置Cookie有效期和删除Cookie cookie.setMaxAge(24*60*60); // Cookie有效时间 co......

二营长意大利炮 ⋅ 今天 ⋅ 0

【每天一个JQuery特效】淡入淡出显示或隐藏窗口

我是JQuery新手爱好者,有时间就练练代码,防止手生,争取每天一个JQuery练习,在这个博客记录下学习的笔记。 本特效主要采用fadeIn()和fadeOut()方法显示淡入淡出的显示效果显示或隐藏元...

Rhymo-Wu ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部