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在执行效率方面确 ...
随机推荐
- linux ssh文件输
在linux下一般用scp这个命令来通过ssh传输文件. 1.从服务器上下载文件scp username@servername:/path/filename /var/www/local_dir(本地 ...
- linux下常用命令失效
注意:修改一下PATH环境变量 export PATH=/bin:/usr/bin/:. 可以把这句话加到你的.profile或者.bash_profile里,这样每次登录的时候都会生效
- 打开手机摄像头扫描二维码或条形码全部操作(代码写的不好,请提出指教,共同进步,我只是一个Android的小白)
(1)下载二维码的库源码 链接:http://pan.baidu.com/s/1pKQyw2n 密码:r5bv 下载完成后打开可以看到 libzxing 的文件夹,最后添加进 Android Stu ...
- (转)C#开发微信门户及应用(1)--开始使用微信接口
http://www.cnblogs.com/wuhuacong/p/3613826.html 微信应用如火如荼,很多公司都希望搭上信息快车,这个是一个商机,也是一个技术的方向,因此,有空研究下.学习 ...
- apicloud图片上传
app中的图片上传,例如:个人信息页面,上传头像 使用: UIMediaScanner 地址: https://docs.apicloud.com/Client-API/UI-Layout/UIMed ...
- Hadoop-2.2.0在Unbuntu ADM64中需要重新编译Native Lib
通过:cat /etc/issue 查看当前系统版本: Ubuntu 12.04.3 通过:uname -ar 查看更想起信息: Linux ubuntu-236 3.8.0-29-generic # ...
- Python 切片 day3
你可以处理列表的部分元素——Python称之为切片 . 一.使用方法: 要创建切片,可指定要使用的第一个元素和最后一个元素的索引. 与函数range() 一样,Python在到达你指定的第二个索引前面 ...
- Html-如何正确给table加边框
一般来说,给表格加边框都会出现不同的问题,以下是给表格加边框后展现比较好的方式 <style> table,table tr th, table tr td { border:1px so ...
- buildroot的make menuconfig配置
开始对buildroot 编译 [root@xxxxxx /data/sandbox/open_linux/buildroot] #make -j 20 Your Perl installation ...
- java获取当前日期的前一天,前一月和前一年
核心:使用Calendar的add(int field, int amount)方法 Calendar ca = Calendar.getInstance();//得到一个Calendar的实例 ca ...