栈解决程序的运行问题,即程序如何执行,或者说如何处理数据;算法
堆解决的是数据存储的问题,即数据怎么放、放在哪儿。缓存
在Java中一个线程就会相应有一个线程栈与之对应,这点很容易理解,由于不一样的线程执行逻辑有所不一样,所以须要一个独立的线程栈。而堆则是全部线程共享的。栈由于是运行单位,所以里面存储的信息都是跟当前线程(或程序)相关信息的。包括局部变量、程序运行状态、方法返回值等等;而堆只负责存储对象信息。服务器
堆中存的是对象。栈中存的是基本数据类型和堆中对象的引用。一个对象的大小是不可估计的,或者说是能够动态变化的,可是在栈中,一个对象只对应了一个4btye的引用(堆栈分离的好处:))。并发
http://pengjiaheng.iteye.com/blog/518623优化
一个空Object对象的大小是8byte,但须要占用4byte+8byte,其中4byte是Java栈中保存引用的所须要的空间。8byte则是Java堆中对象的信息。spa
强引用:就是咱们通常声明对象是时虚拟机生成的引用,强引用环境下,垃圾回收时须要严格判断当前对象是否被强引用,若是被强引用,则不会被垃圾回收操作系统
软引用:软引用通常被作为缓存来使用。与强引用的区别是,软引用在垃圾回收时,虚拟机会根据当前系统的剩余内存来决定是否对软引用进行回收。若是剩余内存比较紧张,则虚拟机会回收软引用所引用的空间;若是剩余内存相对富裕,则不会进行回收。换句话说,虚拟机在发生OutOfMemory时,确定是没有软引用存在的。线程
弱引用:弱引用与软引用相似,都是做为缓存来使用。但与软引用不一样,弱引用在进行垃圾回收时,是必定会被回收掉的,所以其生命周期只存在于一个垃圾回收周期内。对象
http://pengjiaheng.iteye.com/blog/519471blog
垃圾回收算法:
按照基本回收策略分
引用计数(Reference Counting)
标记-清除(Mark-Sweep)
复制(Copying)
标记-整理(Mark-Compact)
增量收集(Incremental Collecting)/分代收集(Generational Collecting)
按系统线程分:串行收集/并行收集/并发收集
http://pengjiaheng.iteye.com/blog/520228
********* http://pengjiaheng.iteye.com/blog/523230
年轻代(Young Generation),又分 一个Eden区,两个Survivor区(通常而言)。
年老点(Old Generation)
持久代(Permanent Generation)。
GC有两种类型:
Scavenge GC:当新对象生成,而且在Eden申请空间失败时,就会触发Scavenge GC,对Eden区域进行GC,清除非存活对象,而且把尚且存活的对象移动到Survivor区。而后整理Survivor的两个区。
Full GC:对整个堆进行整理,包括Young、Tenured和Perm。
http://pengjiaheng.iteye.com/blog/524024
串行处理器:
--适用状况:数据量比较小(100M左右);单处理器下而且对响应时间无要求的应用。
--缺点:只能用于小型应用
并行处理器:
--适用状况:“对吞吐量有高要求”,多CPU、对应用响应时间无要求的中、大型应用。举例:后台处理、科学计算。
--缺点:垃圾收集过程当中应用响应时间可能加长
并发处理器:
并发收集器主要减小年老代的暂停时间,他在应用不中止的状况下使用独立的垃圾回收线程,跟踪可达对象。在每一个年老代垃圾回收周期中,在收集初期并发收集器 会对整个应用进行简短的暂停,在收集中还会再暂停一次。第二次暂停会比第一次稍长,在此过程当中多个线程同时进行垃圾回收工做。
--适用状况:“对响应时间有高要求”,多CPU、对应用响应时间有较高要求的中、大型应用。举例:Web服务器/应用服务器、电信交换、集成开发环境。
http://pengjiaheng.iteye.com/blog/528034
32位系统下,通常限制在1.5G~2G;64为操做系统对内存无限制。
JVM参数设置
http://pengjiaheng.iteye.com/blog/538582
年轻代大小选择
响应时间优先的应用:尽量设大,直到接近系统的最低响应时间限制(根据实际状况选择)。在此种状况下,年轻代收集发生的频率也是最小的。同时,减小到达年老代的对象。
吞吐量优先的应用:尽量的设置大,可能到达Gbit的程度。由于对响应时间没有要求,垃圾收集能够并行进行,通常适合8CPU以上的应用。
年老代大小选择
响应时间优先的应用:年老代使用并发收集器,因此其大小须要当心设置,通常要考虑并发会话率和会话持续时间等一些参数。若是堆设置小了,能够会形成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式;若是堆大了,则须要较长的收集时间。最优化的方案,通常须要参考如下数据得到:
1. 并发垃圾收集信息
2. 持久代并发收集次数
3. 传统GC信息
4. 花在年轻代和年老代回收上的时间比例
减小年轻代和年老代花费的时间,通常会提升应用的效率
吞吐量优先的应用
通常吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代。缘由是,这样能够尽量回收掉大部分短时间对象,减小中期的对象,而年老代尽存放长期存活对象。
较小堆引发的碎片问题
由于年老代的并发收集器使用标记、清除算法,因此不会对堆进行压缩。当收集器回收时,他会把相邻的空间进行合并,这样能够分配给较大的对象。可是,当堆空间较小时,运行一段时间之后,就会出现“碎片”,若是并发收集器找不到足够的空间,那么并发收集器将会中止,而后使用传统的标记、清除方式进行回收。若是出现“碎片”,可能须要进行以下配置:
1. -XX:+UseCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩。
2. -XX:CMSFullGCsBeforeCompaction=0:上面配置开启的状况下,这里设置多少次Full GC后,对年老代进行压缩
http://pengjiaheng.iteye.com/blog/545015
新一代垃圾回收算法 G1
G1可谓博采众家之长,力求到达一种完美。他吸收了增量收集优势,把整个堆划分为一个一个等大小的区域(region)。内存的回收和划分都以region为单位;同时,他也吸收了CMS的特色,把这个垃圾回收过程分为几个阶段,分散一个垃圾回收过程;并且,G1也认同分代垃圾回收的思想,认为不一样对象的生命周期不一样,能够采起不一样收集方式,所以,它也支持分代的垃圾回收。为了达到对回收时间的可预计性,G1在扫描了region之后,对其中的活跃对象的大小进行排序,首先会收集那些活跃对象小的region,以便快速回收空间(要复制的活跃对象少了),由于活跃对象小,里面能够认为多数都是垃圾,因此这种方式被称为Garbage First(G1)的垃圾回收算法,即:垃圾优先的回收。
http://pengjiaheng.iteye.com/blog/548472
调优方法,内存泄漏检查
http://pengjiaheng.iteye.com/blog/552456
http://pengjiaheng.iteye.com/blog/558619
http://pengjiaheng.iteye.com/blog/558620