《转载》JVM垃圾回收机制
每个Java程序员迟早都会碰到下面这个错误:
- java.lang.OutOfMemoryError
这个时候一般会建议采用如下方式解决这个错误:
- 增加MaxPermSize值
- 增加最大堆内存到512M(-xmx参数)
这篇文章会具体介绍Java堆空间和参数MaxPermSize的含义。这篇文章涉及下列主题,并采用Hotspot JVM:
- 垃圾回收器(Garbage Collector,GC)
- 哪个JVM?
- JVM命令行选项
垃圾回收器
垃圾回收器负责:
- 分配内存
- 保证所有正在被引用的对象还存在于内存中
- 回收执行代码已经不再引用的对象所占的内存
应用执行时,定位和回收垃圾对象的过程会占用总执行时间的将近25%,这会拖累应用的执行效率。
Hotspot VM提供的垃圾回收器是一个分代垃圾回收器(Generational GC)[9,16,18]-将内存划分为不同的阶段,也就是说,不同的生命周期的对象放置在不同的地址池中。这样的设计是基于弱年代假设(Weak Generational Hypothesis):
1.越早分配的对象越容易失效;
2.老对象很少会引用新对象。
这种分代方式可以减少垃圾回收的停顿时间以及大范围对象的回收成本。Hotspot VM将其堆空间分为三个分代空间:
1. 年轻代(Young Generation)
○ Java应用在分配Java对象时,这些对象会被分配到年轻代堆空间中去
○ 这个空间大多是小对象并且会被频繁回收
○ 由于年轻代堆空间的垃圾回收会很频繁,因此其垃圾回收算法会更加重视回收效率
2. 年老代(Old Generationn)
○ 年轻代堆空间的长期存活对象会转移到(也许是永久性转移)年老代堆空间
○ 这个堆空间通常比年轻代的堆空间大,并且其空间增长速度较缓
○ 由于大部分JVM堆空间都分配给了年老代,因此其垃圾回收算法需要更节省空间,此算法需要能够处理低垃圾密度的堆空间
3. 持久代(Permanent Generation)
○ 存放VM和Java类的元数据(metadata),以及interned字符串和类的静态变量
次收集(Minor GC)和全收集(Full GC)
当这三个分代的堆空间比较紧张或者没有足够的空间来为新到的请求分配的时候,垃圾回收机制就会起作用。有两种类型的垃圾回收方式:次收集和全收集。当年轻代堆空间满了的时候,会触发次收集将还存活的对象移到年老代堆空间。当年老代堆空间满了的时候,会触发一个覆盖全范围的对象堆的全收集。
次收集
- 当年轻代堆空间紧张时会被触发
- 相对于全收集而言,收集间隔较短
全收集
- 当老年代或者持久代堆空间满了,会触发全收集操作
- 可以使用System.gc()方法来显式的启动全收集
- 全收集一般根据堆大小的不同,需要的时间不尽相同,但一般会比较长。不过,如果全收集时间超过3到5秒钟,那就太长了[1]
全收集通常时间最长,并且是程序无法延迟执行或者无法达到吞吐量目标的主因。GC的目标是去减少程序运行过程中垃圾回收的频率。为了达到这个目的,可以从这两方面入手:
- 从系统方面考虑:
○ 尽量采用大堆,但是不要大到需要系统从磁盘上“换”页。一般而言,可用的RAM(没有被系统进程占用的)的80%都应该分配给JVM。
○ Java堆空间越大,垃圾回收器和java应用在吞吐量(throughput)和延迟执行(latency)方面的效果越好。
- 从应用方面考虑:
○ 减少对象分配(object allocations)操作,或者采用对象保留(object retention)方式有助于减小存活的数据大小,这也可以反过来帮助垃圾回收做的更好。
○ 参考这篇文章—Java性能提升窍门[19]
内存溢出错误(OutOfMemoryError)
可怕的内存溢出错误是Java程序员最不愿意看到的。然而这个错误还是会出现,尤其应用中涉及到大量的数据处理时,或应用运行时间过长时。
一个应用所占内存大小包括:
- Java堆大小
- 线程栈
- I/O缓冲区
- 原生库所分配的内存
当一个应用耗尽了内存并且JVM GC也无法回收任何对象空间的时候,就会发生内存溢出错误。但是,内存溢出错误并不一定就意味着内存泄露(memory leak)。也有可能只是一个配置问题,例如设置的堆大小(如果没有设置那就是缺省的堆大小)对于应用来说是不够用的。
JVM命令行参数
无论是客户端应用还是服务器端应用,一旦系统运行缓慢并且垃圾回收所占时间过长,你就会希望通过调整堆大小来改善这一点。不过,为了不影响其他也跑在同一个系统中的应用,不应该将堆大小设置的过大。
GC调优是很重要的。找到最佳的分代堆空间是一个迭代的过程[3,10,12]。这里我们假定你已经为你的应用找到了最佳堆大小。那么你可以采用下面的JVM命令来进行设置:
GC 命令行选项 | 描述 |
-Xms | 设置Java堆大小的初始值/最小值。例如:-Xms512m (请注意这里没有”=”). |
-Xmx | 设置Java堆大小的最大值 |
-Xmn | 设置年轻代对空间的初始值,最小值和最大值。请注意,年老代堆空间大小是依赖于年轻代堆空间大小的 |
-XX:PermSize=<n>[g|m|k] | 设置持久代堆空间的初始值和最小值 |
-XX:MaxPermSize=<n>[g|m|k] | 设置持久代堆空间的最大值 |
最后一点,最早在Java SE 5.0中有对服务器的人机工程学的介绍[13]。这个可以很好的减少服务器端应用的调优时间,尤其是在堆大小测量和复杂GC调优方面。很多情况下,服务器端调优的最好方式就是不去调优。
参考文章
1 Tuning Java Virtual Machines (JVMs)
2 Diagnosing Java.lang.OutOfMemoryError
3 Java Performance by Charlie Hunt and Binu John
5 GCViewer (a free open source tool)
6 Comparison Between Sun JDK And Oracle JRockit
7 Java SE 6 Performance White Paper
8 F&Q about Garbage Collection
10 Memory Management in the Java HotSpot Virtual Machine White Paper
11 Java Hotspot Garbage Collection
12 FAQ about GC in the Hotspot JVM (with good details)
13 Java Heap Sizing: How do I size my Java heap correctly?
15 JRockit JVM Heap Size Options
16 Pick up performance with generational garbage collection
17 Which JVM?
18 Memory Management in the Java HotSpot™ Virtual Machine
英文原文: XML and more,翻译:ImportNew - 郑雯
译文地址: http://www.importnew.com/1551.html
《转载》JVM垃圾回收机制的更多相关文章
- [转载]JVM 垃圾回收机制(Garbage Collection)
相关算法: 引用计数法 引用可达法 尚学堂 参考:http://www.sxt.cn/Java_jQuery_in_action/Principle_and_algorithm_of_garbage_ ...
- JVM垃圾回收机制总结:调优方法
转载: JVM垃圾回收机制总结:调优方法 JVM 优化经验总结 JVM 垃圾回收器工作原理及使用实例介绍
- JVM内存管理和JVM垃圾回收机制
JVM内存管理和JVM垃圾回收机制(1) 这里向大家描述一下JVM学习笔记之JVM内存管理和JVM垃圾回收的概念,JVM内存结构由堆.栈.本地方法栈.方法区等部分组成,另外JVM分别对新生代和旧生代采 ...
- JVM垃圾回收机制概述
JVM垃圾回收机制概述 1.定义 是指JVM用于释放那些不再使用的对象所占用的内存. 2.方式 2.1引用计数(早期) 当引用程序创建引用以及引用超出范围时,JVM必须适当增减引用数.当某个对象的引用 ...
- Java虚拟机学习笔记——JVM垃圾回收机制
Java虚拟机学习笔记——JVM垃圾回收机制 Java垃圾回收基于虚拟机的自动内存管理机制,我们不需要为每一个对象进行释放内存,不容易发生内存泄漏和内存溢出问题. 但是自动内存管理机制不是万能药,我们 ...
- JVM基础系列第8讲:JVM 垃圾回收机制
在第 6 讲中我们说到 Java 虚拟机的内存结构,提到了这部分的规范其实是由<Java 虚拟机规范>指定的,每个 Java 虚拟机可能都有不同的实现.其实涉及到 Java 虚拟机的内存, ...
- JVM内存管理、JVM垃圾回收机制、新生代、老年代以及永久代
内存模型 JVM运行时数据区由程序计数器.堆.虚拟机栈.本地方法栈.方法区部分组成,结构图如下所示. JVM内存结构由程序计数器.堆.栈.本地方法栈.方法区等部分组成,结构图如下所示: 1)程序计数器 ...
- JVM 垃圾回收机制和常见算法和 JVM 的内存结构和内存分配(面试题)
一.JVM 垃圾回收机制和常见算法 Sun 公司只定义了垃圾回收机制规则而不局限于其实现算法,因此不同厂商生产的虚拟机采用的算法也不尽相同.GC(Garbage Collector)在回收对象前首先必 ...
- JVM垃圾回收机制和常用算法
由于疫情的原因,所以目前一直在家远程办公,所以很多时间在刷面试题,发现2019大厂的面试虽然种类很多,但是总结了一下发现主要是这几点:算法和数据结构. JVM.集合.多线程.数据库这几点在面试的时候比 ...
- 真的可惜,四面阿里,结果我被JVM垃圾回收机制与 OOM异常卡住了
前言 为什么需要垃圾回收 首先我们来聊聊为什么会需要垃圾回收,假设我们不进行垃圾回收会造成什么后果,我们举一个简单的例子 我们住在一个房子里面,我们每天都在里面生活,然后垃圾都丢在房子里面,又不打扫, ...
随机推荐
- openstack 之~keystone基础
第一:keystone是什么? keystone是 OpenStack Identity Service 的项目名称,是一个负责身份管理验证.服务规则管理和服务令牌功能.它实现了openstack的i ...
- django之模型层(model)--查询补充及cookie
已经连续写了好几篇django的模型层(model)增删改查的随笔了,没篇大篇幅都是查询相关的操作,可以看出查询在数据的操作中是多么的重要,而本篇最后再补充一点关于关于查询的一些方法,模型层基本的操作 ...
- nvidia-smi命令输出详解
nvidia-smi命令输出如下: +-----------------------------------------------------------------------------+ | ...
- Dubbo接口压测
在每年的双十一大促之前,除了全链路压测,还需要各个业务方对自己业务提供的核心接口进行单接口压测,以评判系统的稳定性和承压能力. 一.准备工作 环境准备:确保应用性能环境(perf)正常可用 压测接口梳 ...
- [C#] 解决Silverlight反射安全关键(SecuritySafeCritical)时报“System.MethodAccessException: 安全透明方法 XXX 无法使用反射访问”的问题
作者: zyl910 一.缘由 在Silverlight中使用反射动态访问时,经常遇到"System.MethodAccessException: 安全透明方法 XXX 无法使用反射访问-- ...
- 全栈JavaScript之路(十九)HTML5 插入 html标记 ( 一 )innerHTML 与outerHTML
在须要给文档插入大量的html 标记下.通过DOM操作非常麻烦,你不仅要创建一系列的节点,并且还要小心地依照顺序把它们接结起来. 利用html 标签 插入技术,能够直接插入html代码字符串,简单.高 ...
- 基于 Python 官方 GitHub 构建 Python 文档
最近在学 Python,所以总是在看 Python 的官方文档, https://docs.python.org/2/ 因为祖传基因的影响,我总是喜欢把这些文档保存到本地,不过 Python 的文档实 ...
- webstorm快捷键 webstorm keymap内置快捷键英文翻译、中英对照说明
20160114参考网络上的快捷键,整理自己常用的: 查找/代替shift+shift 快速搜索所有文件,简便ctrl+shift+N 通过文件名快速查找工程内的文件(必记)ctrl+shift+al ...
- 关于asyncio知识(四)
一.使用 asyncio 总结 最近在公司的一些项目中开始慢慢使用python 的asyncio, 使用的过程中也是各种踩坑,遇到的问题也不少,其中有一次是内存的问题,自己也整理了遇到的问题以及解决方 ...
- 关于asyncio知识(一)
一.介绍 asyncio 是python3.4 引入的一个新的并发模块,主要通过使用coroutines 和 futures 来让我们更容易的去实现异步的功能,并且几乎和写同步代码一样的写代码,还没有 ...