网站首页 > java教程 正文
前言
Java的垃圾回收机制让开发者可以把更多的精力投入到业务和逻辑中,少关注内存的管理(JVM会自动将垃圾内存进行回收),降低了程序员的工作难度。但是在当今互联网的环境下,高并发,高可用的需求下,充分理解垃圾回收机制才能更好的完成工作。
这就需要我们对于虚拟机对内存的管理方式,方法,垃圾回收的方法,策略有很好的了解。下面我们可以带着问题去阅读:
JVM如何管理内存
JVM如何确定某些内存为垃圾需要回收
JVM如何在不影响正在运行程序的同时进行垃圾回收
JVM运行区域
JVM在管理内存的时候会将内存划分为不同的数据区域,这些数据区域各有各的用途。
JVM运行时数据区域
程序计数器
比较小的内存空间,可以看成当前程序所执行的字节码的行号指示器。在我们进行JVM优化的时候基本上不用考虑它。
虚拟机栈
描述了Java方法执行的内存模型,每个方法执行的时候会创建栈帧,存储局部变量表、操作数、动态连接、返回地址等。调用方法的过程是一个进栈和出栈的过程。
本地方法栈
为虚拟机使用到的Native方法提供服务,与虚拟机栈有点类似
堆
虚拟机所管理的内存中最大的一块。被所有的线程所共享,虚拟机启动的时候创建。用于存放对象的实例。也是垃圾收集器的主要工作区域。
方法区
各个线程共享的内存区域,存储被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。运行时常量池是方法区的一部分,存放编译期间生产的各种字面量和符号引用。
Java对象的前世今生
为了更好的理解垃圾回收,让我们先看看对象的整个生命周期,从诞生到消亡的过程。
产生过程:
new 指令创建对象
检查常量池中是否有创建类的符号引用,并检查此引用是否被加载,解析和初始化过
虚拟机为对象分配空间(此时对象的大小以及确定)
分配的空间初始化为0
对对象进行必要的设置:那个类的实例,类的元数据,对象的Hash值等。存放在对象头中。
至此对象JVM中对象已经产生,可以开始执行Java的代码
生存状态:
对象在内存中有3块区域:对象头,实例数据,对其填充
当我们建立对象的时候,会在栈上有一个对象的引用来访问对象
对象的消亡:
对象不在被引用会被JVM标记为垃圾
通过JVM的垃圾回收机制(本文描述的重点)将对象销毁内存释放
什么是垃圾
我们把JVM的内存回收叫做垃圾回收机制。到底什么是垃圾,通过字面理解,既然是垃圾就是不再使用的对象啦,JVM如何去判断那?
答案:JVM通过一种可达性分析算法来确定对象是否为垃圾。简单的说,就好像树林中,对象是叶子,如果叶子不能可以沿着枝条(引用关系)找到任何一颗树根,则这个叶子是垃圾(应该已经掉落在地上了)。树根==GC Root;枝条==引用关系;叶子==对象
下面的问题来了,JVM中的GC Root都有什么??
虚拟机栈中引用的对象
方法区中静态属性引用的对象
方法区中常量引用的对象
方法区栈JNI中引用的对象
垃圾回收算法
通过之前的阅读,我们大体可以得到如下的结论:
垃圾回收主要集中在堆上
方法区中有大量的常量和类(如果使用反射和动态代理等框架,产生大量的动态类的情况下,需要考虑类卸载的问题)
知道了那些类会被定义为垃圾
现在的问题是,什么时间,如何进行垃圾回收?
我们先看看垃圾回收的主要算法
标记-清除
灰色表示需要释放的内存
经历2个步骤,第一步进行标记(找出垃圾),第二步进行清理(释放内存)。会产生很多内存碎片
复制
两个区域相互拷贝
使用一半的内存,交替使用。内存没有碎片,但是会浪费一半的资源标记-整理
和标记清除类似,但是没有内存碎片
垃圾回收实现
现代的JVM都使用分代收集算法,主要是根据对象存活的周期不同将内存分为几个块。一般分为:新生代,老年代。
新生代:存储的对象都是很快会被回收的对象,只有少量存活,由于存活的比较少,使用复制算法将比较合适。新生代中还可以细分3个区:Eden,S1,S2。
老年代:对象存活率比较高,可以使用标记清除或者标记整理来实现垃圾回收
GC有2种:
Minor GC
又称新生代GC,指发生在新生代的垃圾收集动作;
因为Java对象大多是朝生夕灭,所以Minor GC非常频繁,一般回收速度也比较快;
触发条件:当Eden区满时,触发Minor GC。
Full GC
又称Major GC或老年代GC,指发生在老年代的GC;
出现Full GC经常会伴随至少一次的Minor GC(不是绝对,Parallel Sacvenge收集器就可以选择设置Major GC策略);
Major GC速度一般比Minor GC慢10倍以上;
Full GC触发条件:
(1)调用System.gc时,系统建议执行Full GC,但是不必然执行
(2)老年代空间不足
(3)方法区空间不足
(4)通过Minor GC后进入老年代的平均大小大于老年代的可用内存
(5)由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小
垃圾回收器
HotSpot虚拟机提供了如下几种垃圾回收器
垃圾回收器示意图
连线表示可以搭配使用
Serial收集器:
单线程,会暂停所有的工作进行垃圾回收,默认用于Java client中。设置参数:-XX:+UseSerialGC
ParNew:
Serial的多线程版本
Parallel Scavenge:
新生代的收集器,使用复制算法,并行的多线程收集器。主要的特点是控制吞吐量。
CMS:
是一种以最小停顿为目标的设计方案,是基于标记-清除的算法
Serial Old:
Serial收集器的老年代版本,可以作为CMS收集器的后备预案,在并发收集发生Concurrent Mode Failure时使用
Parallel Old:
Parallel Scavenge收集器的老年代版本
G1:
面向服务端应用的收集器,并行与并发;分代收集;空间整合;可预期的停顿
猜你喜欢
- 2024-10-22 降低Java垃圾回收开销的5条建议(java具有自动垃圾回收机制吗)
- 2024-10-22 垃圾回收算法(垃圾回收算法手册 pdf)
- 2024-10-22 成为JavaGC专家(2)—如何监控Java垃圾回收机制
- 2024-10-22 Java中的垃圾回收算法与垃圾回收器
- 2024-10-22 java垃圾回收算法(java垃圾回收的算法)
- 2024-10-22 Java垃圾回收机制详解(java垃圾回收机制详解怎么写)
- 2024-10-22 java虚拟机——垃圾收集器与回收策略
- 2024-10-22 Java 常见的垃圾回收算法以及它们的优缺点(总结版)
- 2024-10-22 用最直接的大白话聊一聊Java对象的GC垃圾回收及在内存中的那些事
- 2024-10-22 从引用聊一聊 Java 垃圾回收(java中垃圾回收有什么目的)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)