JVM内存结构、垃圾回收那点事(转)
翻看电脑的文件夹,无意看到了9月份在公司做的一次分享,浏览了一下"婆婆特",发现自己在ppt上的写的引导性问题自己也不能确切的回答出来,哎,知识这东西,平时不常用的没些日子就生疏了。于是,本小白决定把他整理下来,不敢班门弄斧,对于入门的同学可以快速了解虚拟机的大概,有错误的地方请批评指正。
一、java虚拟机的内存结构



public class ReferenceCountGc {
public Object field = null;
public static void main(String[] args) {
ReferenceCountGc objA = new ReferenceCountGc();
ReferenceCountGc objB = new ReferenceCountGc();
objA.field = objB;
objB.field = objA;
objA = null;
objB = null;
System.gc();
}
}
当程序执行到System.gc()时,是否会回收对象objA和objB?
引用计数方法:给对象一个计数器,当对象被引用时就+1,释放掉引用-1,当为0时及不会再被引用。但引用计数方法的Bug是无法解决对象循环引用的问题,但并不是此算法没有用武之地,在很多场景下会使用到这个算法。但java的垃圾回收并没有使用。上面的程序如果使用的是引用计数算法则不会被回收,但虚拟机却使用根搜索算法。
根搜索算法即设定一个对象称为GC root ,从这个节点向下进行搜索,搜索所走过的路径称为引用链,当GC root没有任何引用链相连即在图论中不可到达,则证明此对象不可用
由此来看看,对象死后,垃圾回收算法;
标记-清除算法 复制算法
灰色矩形框为可回收对象,标记-清除算法就是把可回收的对象进行标记,标记到一定次数则清除掉。从图中可以明显看出,该算法的弊端是会产生大量的磁盘碎片,没有一整片连续的空间,当遇到占用连续的内存空间较多的对象时,由于内存放不下该对象,会提前进行垃圾回收,致使虚拟机垃圾回收频繁,影响性能
为了规避标记清除算法的弊端,出现了复制算法,复制算法将内存一份为二,垃圾回收时将使用的内存中的存活对象,拷贝到另一半内存中,然后把左侧内存区域完全清除掉,上图只是演示了复制算法,但并非一分为二,使用和保留的空间是1:1,可以根据实际情况对虚拟机参数进行调整。此算法的弊端是要保留内存空间,会将可用内存变少。
标记整理算法: 分代收集算法:
标记整理算法:绿色和蓝色区域都代表存活对象,当进行垃圾回收时把存活对象依次移到最左边,移动后将其余内存空间清空。
分代收集算法:如图,其实就是没有算法。。。把以上3种算法进行综合运用,前面说过堆是有划分的,简单分为新生代和老年代,分代收集就是根据不同代的特点应用不同的垃圾回收算法。
三、java内存分配
java的自动内存管理解决了两个问题,一是给对象分配内存,二是回收分配给对象的内存,前面我们讲了回收分配给对象的内存,下面我们来看看给对象分配内存
java堆分为新生代,老年代(终身代)和永久代。
新生代和老年代的默认比值为1:2即新生代占堆总内存的1/3,可以通过 –Xms(初始堆大小)、-Xmx (最大堆大小)来改变。
新生代又分为Eden区、From survivor区、To survivor区,Eden:From:To 为 8:1:1,可以通过–XX:SurvivorRatio 参数设定。
JVM每次只会使用From区和survivor区中的一块(Form survivor或To survivor),很明显是为了在垃圾回收的时候将存活对象移到另外一个空闲的survivor区(如果空间足够,否则直接进入老年代),因此垃圾回收所使用的算法是复制算法。
新生的对象会被分配到新生代,新生代的特点是朝生夕死,对象存活的时间短,迭代快。发生在新生代的垃圾回收叫minor GC,minor Gc进行的相对频繁,消耗较full GC少,而Full GC是发生在老年代的垃圾回收,采用的是标记-清除算法。老年代进行一次垃圾回收比新生代话费时间长,进行的也没有老年代频繁,同时要尽量减少老年代的垃圾回收,因为回收速度慢且在进行时影响虚拟机性能,使虚拟机响应变慢,最直接的感觉是应用程序的响应速度变慢。
什么情况下,对象会被分配到老年代?
从上图中明显可以到3点:
大对象:什么是大对象,大对象就是需要连续占用很多内存空间的对象比如很长的字符串和数组。虚拟机通过-XX:PretrnureSizeThreshold设计大过指定大小的对象之间进入老年代,即时没有超过指定大小,在进行minor GC时通常也会因为survivor区不够用而被转移到老年代。
通过设置MaxTenuringThreshold参数: 这个参数是进行年龄设置的,超过这个年龄的会进入老年代。什么是年龄?在新生代进行minor GC的时候,每进行一次,存活下来的对象年龄+1,默认年龄超过15的会进入老年代。15这个数值也可以通过MaxTenuringThreshold参数改变。
Survivor空间中相同年龄所有对象大小的总和大于survivor空间的一半,所有大于或者等于该年龄的对象直接进入老年代,这句话比较拗口,但就是这个意思,看不懂的多看几遍就好了。。。
前面讲了这么多参数,如何设置虚拟机参数?可以通过IDE进行设置,不论是调整空间大小,还是设置对象的年龄进入老年代,如下图
三、我们开发中应注意的问题
从虚拟机上可以看出,主要是避免full GC的次数,减少朝生夕死的大对象,对虚拟机内存进行优化,在日常开发中写程序的主要注意的是
不要使用长字符串 如:String x = new String(“XXXXXXXXXXXX”) StringBuffer stringBuffer = new StringBuffer()StringBuffer对象的append()方法。当然,考虑到线程安全问题,使用StringBuilder.
JVM内存结构、垃圾回收那点事(转)的更多相关文章
- Java进阶 JVM 内存与垃圾回收篇(一)
JVM 1. 引言 1.1 什么是JVM? 定义 Java Vritual Machine - java 程序的运行环境(Java二进制字节码的运行环境) 好处 一次编译 ,到处运行 自动内存管理,垃 ...
- Java内存与垃圾回收调优
Java(JVM)内存模型 正如你从上面的图片看到的,JVM内存被分成多个独立的部分.广泛地说,JVM堆内存被分为两部分——年轻代(Young Generation)和老年代(Old Generat ...
- 【转】Java内存与垃圾回收调优
要了解Java垃圾收集机制,先理解JVM内存模式是非常重要的.今天我们将会了解JVM内存的各个部分.如何监控以及垃圾收集调优. Java(JVM)内存模型 正如你从上面的图片看到的,JVM内存被分成多 ...
- 面试~jvm(JVM内存结构、类加载、双亲委派机制、对象分配,了解垃圾回收)
一.JVM内存结构 ▷ 谈及内存结构各个部分的数据交互过程:还可以再谈及生命周期.数据共享:是否GC.是否OOM 答:jvm 内存结构包括程序计数器.虚拟机栈.本地方法栈.堆.方法区:它是字节码运行时 ...
- 推荐收藏系列:一文理解JVM虚拟机(内存、垃圾回收、性能优化)解决面试中遇到问题(图解版)
欢迎一起学习 <提升能力,涨薪可待篇> <面试知识,工作可待篇 > <实战演练,拒绝996篇 > 欢迎关注我博客 也欢迎关注公 众 号[Ccww笔记],原创技术文章 ...
- 【转】jvm内存结构
JVM的基本结构 包括四部分:类加载器.执行引擎.内存区(运行时数据区).本地方法接口 类加载器:jvm启动时或类运行时将需要的class文件加载到JVM中. JVM内存申请过程如下: JVM 会试图 ...
- 【JVM】JVM系列之垃圾回收(二)
一.为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收.除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此.所以,垃圾回收是必须的. 二. ...
- JVM内存结构之三--持久代
本文会介绍一些JVM内存结构的基本概念,然后很快会讲到持久代,来看下Java SE 8发布后它究竟到哪去了. 基础知识 JVM只不过是运行在你系统上的另一个进程而已,这一切的魔法始于一个java命令. ...
- 最简单例子图解JVM内存分配和回收
一.简介 JVM采用分代垃圾回收.在JVM的内存空间中把堆空间分为年老代和年轻代.将大量(据说是90%以上)创建了没多久就会消亡的对象存储在年轻代,而年老代中存放生命周期长久的实例对象.年轻代中又被分 ...
- JVM内存结构
前言 在Java语言开发过程中,out of memory错误是很常见的一种错误.对于JVM的内存结构有更深入的了解,更更好的帮我们排查此类问题,有效的避免此类问题发生.在JAVA 8中内存结构有进行 ...
随机推荐
- 复习面向对象的OOA、OOD、OOP
复习 OOA.OOD.OOP OOA Object-Oriented Analysis:面向对象分析方法 是在一个系统的开发过程中进行了系统业务调查以后,依照面向对象的思想来分析问题. OOA与结构化 ...
- JavaScript 使用Document记录cookie
cookie对于我们使用者来说,有时帮助还是挺大的,比方对于一些不是特别重要的站点,比方公司的測试平台,每次登陆都要手动输入username和password 非常繁琐.所以为了更少的引入其他框架,就 ...
- Eclipse设置的断点失效的解决办法
使用Eclipse的同胞们,如果你哪天惊奇的发现调试时,明明设置了断点,按道理就是要执行设置断点的那条语句的,可是偏偏Eclipse视你设置的断点不见,不要害怕,不要恐慌,这样的问题不应该导致偶们疯狂 ...
- Smarty模板引擎的使用
Smarty模板引擎的使用 Smarty是PHP中一个基于MVC模式的模板引擎. Download: http://www.smarty.net/download 特点 1. 最快速度的程序开发 ...
- Android FragmentStatePageAdapter的使用Demo
上一篇写过FragmentPagerAdapter,这篇来介绍FragmentStatePagerAdapter,那么两者之间有何差别呢: FragmentPagerAdapter很多其它的用于少量界 ...
- 【DRP】删除递归树的操作
正如图呈现的树结构.本文从任意节点删除树形结构.提供解决方案 图中,不包括其他结点的是叶子结点.包括其他结点的是父结点,即不是叶子结点. 一 本文的知识点: (1)递归调用: 由于待删除的结点的层次是 ...
- 《JavaScript设计模式与开发实践》读书笔记之模板方法模式
1. 模板方法模式 1.1 面向对象方式实现模板方法模式 以泡茶和泡咖啡为例,可以整理为下面四步 把水煮沸 用沸水冲泡饮料 把饮料倒进杯子 加调料 首先创建一个抽象父类来表示泡一杯饮料 var Bev ...
- Automatically generate serial number in abap
流水号的产生: 在ABAP开发中,很多地方都需要按照自己的规则生成流水号,把这些流水号保存进透明表,作为唯一标示. 一. 系统中设定流水号 使用T-Code SNRO来创建一个流水号标识对象. 输 ...
- ACdream原创群赛(18)のAK's dream题解
只做了4题水题ADGI A题需要注意的就是“[...]”的输出了,何时输出,何时不输出. #include <stdio.h> int main() { int n, cur, d; ; ...
- jQuery插件之-瀑布流插件
jquery.wookmark.js 一个实现瀑布流自适应宽度布局的jQuery插件—jquery.wookmark.js , wookmark使用非常简单到只需要一句代码就能实现,除此之外,当页面宽 ...