Java内存管理及垃圾回收总结
概述
Java和C++的一个很重要的差别在于对内存的管理。Java的自己主动内存管理及垃圾回收技术使得Java程序猿不须要释放废弃对象的内存。从而简化了编程的过程。同一时候也避免了因程序猿的疏漏而导致的内存泄露问题。
内存管理和垃圾回收是JVM很重要的一个部分。深入理解Java的内存管理和垃圾回收机制是避免及修复Java相关异常(OutOfMemoryError, StackOverflowError),理解Java对象创建过程,有效利用内存。构建高性能Java应用的前提。本文将先后介绍Java执行时内存区域,垃圾回收,对象创建过程。
Java执行时内存区域
当中程序计数器,栈,本地方法栈都是线程私有的。堆和方法区被全部线程共享。
因为堆是各个线程共享的内存区域,所以把对象存放在堆中有利于线程之间的通信(共享内存)。正如之前我们在描写叙述栈时所示,JVM会为每一个方法创建一个栈帧,所以假设对象存放在栈中,方法调用的參数将须要从调用方法的栈帧复制到被调用方法的栈帧,假设对象存放在堆中,仅仅须要拷贝指针或引用(此时。两个方法将指向同一个对象)。所以我们能够觉得Java之所以把对象存放在堆中。其一是Java具有很优秀的垃圾回收机制,其二把对象存放在堆中有利于线程之间共享数据及通信,其三是能够降低不必要的对象拷贝。提升方法调用的效率,同一时候也节约了内存。
复制算法就是将存活下来的对象从一个区域拷贝到还有一个区域,标记删除和标记整理就是将须要回收的对象标记出来。然后清除掉,标记整理算法还会对内存进行整理。这样能够避免内存碎片。
将Java堆分成两个不同的年代并採用不同回收算法的垃圾收集方式被称为分代收集。下一节将具体介绍垃圾收集的机制以及经常使用垃圾收集器。
垃圾回收
Java堆採用了新生代为复制算法,老年代为标记-整理或标记-清除算法的分代收集机制。
记住,这三个区域的划分仅仅是逻辑上的,和物理划分无关。默认Eden和Survivor的大小比例为8 : 1,比例划分这么大是为了提高内存的利用率,在这样的比例下可利用的内存事实上仅仅有90%;看到这里,我想非常多人可能会问。假如10%的空间不够存放生存下来的对象怎么办?JVM提供了一种被称为分配担保(Handle
Promotion)的机制,由老年代为To Survivor空间提供担保,假如To Survivor没有足够的空间存放生存下来的对象,这些对象直接存放到老年代,假如老年代还不够存放,就会抛出OutOfMemoryError异常。
这些垃圾收集器的一个差别是单线程还是多线程。当中Serial,Serial Old是单线程的。其余是多线程的。第二个差别是垃圾收集线程和用户线程能否够并发运行。CMS收集器能够分成初始标记,并发标记。又一次标记。并发回收等过程,当中并发标记和并发回收能够与用户线程并发运行。所以它也是这些垃圾收集器中唯一真正意义上的并发收集器;Parallel
Scavenge与ParOld以提高吞吐量为目的。其它收集器以减小停顿时间(Stop The World)为目的。
创建对象及内存分配
= ptr + size。空暇列表是通过将空暇的区域通过链表连接起来。对象须要内存则遍历链表,直到遇到一个具有足够空间的元素为止。内存分配完之后就将所分配的内存初始化为0,每一个对象都有一个对象头,这里保存着和对象相关的锁,对象的哈希码。对象的GC分代年龄,以及指向方法区中类型的相关引用。到此为止。对于虚拟机来说,已经成功创建了一个对象;但从Java程序来说。这才刚刚開始,接下来会运行<init>方法对全部字段进行初始化。
一般来说。优先在Eden空间中分配内存;对于大对象。优先在老年代中分配内存(size大于PrenureSizeThreshold);当对象的年龄大于MaxTenuringThreshold时。对象也会被移动至老年代。假设Survivor空间中同样年龄的全部对象大小总和大于Survivor空间的一半,年龄大于或等于该年龄的对象直接进入老年代。
Java内存管理及垃圾回收总结的更多相关文章
- Java内存管理和垃圾回收
笔记,深入理解java虚拟机 Java运行时内存区域 程序计数器,线程独占,当前线程所执行的字节码的行号指示器,每个线程需要记录下执行到哪儿了,下次调度的时候可以继续执行,这个区是唯一不会发生oom的 ...
- java基础(一):谈谈java内存管理与垃圾回收机制
看了很多java内存管理的文章或者博客,写的要么笼统,要么划分的不正确,且很多文章都千篇一律.例如部分地方将jvm笼统的分为堆.栈.程序计数器,这么分太过于笼统,无法清晰的阐述java的内存管理模型: ...
- Java内存管理 -JVM 垃圾回收
版权声明:本文为博主原创文章,未经博主允许不得转载 一.概述 相比起C和C++的自己回收内存,JAVA要方便得多,因为JVM会为我们自动分配内存以及回收内存. 在之前的JVM 之内存管理 中,我们介绍 ...
- Java基础--Java内存管理与垃圾回收
Java自动内存管理 在讲解内存管理之前,首先需要了解对象和对象引用的区别 对象是类的一个实例,以人这个类为例,Person是我们定义的一个类 public class Person{} publ ...
- java内存管理之垃圾回收及JVM调优
GC(garbage Collector 垃圾收集器)作用:a.内存的动态分配:b.垃圾回收注:Java所承诺的自动内存管理主要是针对对象内存的回收和对象内存的分配. 一.垃圾标记 程序计数器.Jav ...
- Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收
很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确 ...
- JVM原理(Java代码编译和执行的整个过程+JVM内存管理及垃圾回收机制)
转载注明出处: http://blog.csdn.net/cutesource/article/details/5904501 JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.e ...
- java Vamei快速教程22 内存管理和垃圾回收
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 整个教程中已经不时的出现一些内存管理和垃圾回收的相关知识.这里进行一个小小的总结. ...
- JVM内存管理及垃圾回收【转】
很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确 ...
随机推荐
- WPF播放器
最近由于工作需要,需要做一个播放软件,在网上参考了很多例子,园子里有很多代码.其中最多的就是wpf自带的MediaElement控件,或者VLC视频播放器. 先附我自己查询资料的链接: MediaEm ...
- unicode、UTF-8、UTF-16的历史
1:中国人民通过对 ASCII 编码的中文扩充改造,产生了 GB2312 编码,可以表示6000多个常用汉字. 2:汉字实在是太多了,包括繁体和各种字符,于是产生了 GBK 编码,它包括了 GB231 ...
- Android_传感器光学
上一篇写了一个小案例方向传感器,与这光学传感器原理大致类似,但其实代码的主要区别得到的类型不一样在这里我一一列举出来: * Sensor.TYPE_ORIENTATION:方向传感器. * Senso ...
- python tips:匿名函数lambda
lambda用于创建匿名函数,下面两种函数定义方式等价. f = lambda x: x + 2 def f(x): return x + 2 立刻执行的匿名函数 (lambda x: print(x ...
- matlab学习checkbox使用
添加radiobutton1和checkbox2控件以及两个edittextbox控件 %得到控件的值var=get(handles.kj2,'value');%将数值显示到文本框中,将得到的数值转换 ...
- pytorch基础(4)-----搭建模型网络的两种方法
方法一:采用torch.nn.Module模块 import torch import torch.nn.functional as F #法1 class Net(torch.nn.Module): ...
- 修改layui的后台模板的左侧导航栏可以伸缩
原生的左侧导航栏代码: <div class="layui-side layui-bg-black"> <div class="layui-side-s ...
- 使用Layer完成图片放大功能
序言:在写这个功能之前也用了zoom.js,zoom.js用起来简单引用js然后设置图片属性就可以放大.但是放大后的图片模糊.没有遮罩.在放大图片时其它图片布局会受到影响,当然如果觉得这些都是小问题的 ...
- Java开发编码规范
第一章 代码开发规范及其指南 一.1 目的 定义这个规范的目的是让项目中所有的文档都看起来像一个人写的,增加可读性,减少项目组中因为换人而带来的损失.(这些规范并不是一定要绝对遵守,但是一定要让程序有 ...
- Web Service 附件技术的发展及演变
Web Service 通常将业务数据封装在 SOAP 主体或者 SOAP 消息附件中进行传输,这些附件往往采用 Base64 编码二进制方式进行封装,这将大大增加待传输的数据量,消耗比较长的编码时间 ...