Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1234041
  • 博文数量: 220
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1769
  • 用 户 组: 普通用户
  • 注册时间: 2015-03-13 16:19
个人简介

努力, 努力, 再努力

文章分类

全部博文(220)

文章存档

2018年(8)

2017年(46)

2016年(75)

2015年(92)

我的朋友

分类: Java

2017-06-30 16:53:57

http://www.cnblogs.com/xingzc/p/5756119.html

http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html


java中,栈的大小通过-Xss来设置,当栈中存储的数据比较多时,需要适当调大这个值,否则会出现 java.lang.StackOverflowError异常



1.数据类型

2.堆与栈

  (1)为什么要把堆和栈区分出来呢?栈中不是也可以存储数据吗?

  (2)在java中,Main函数就是栈的起始点,也是程序的起始点。

  (3)堆中存什么?栈中存什么?

  (4)java中的参数传递是传值呢?还是传引用?

  (5)java对象的大小

  (6)引用类型: 对象引用类型分为强引用、软引用、弱引用和虚引用

  (7)按照基本回收策略分
   
    引用计数(Reference Counting)

    标记-清除(Mark-Sweep)

    复制(Copying)

    标记-整理(Mark-Compact)

  (8)按分区对待的方式分

    增量收集

    分代收集: 年轻代、年老代、持久代

  (9)按系统线程分:

    串行收集: 串行收集使用单线程处理所有垃圾回收工作

    并行收集: 并行收集使用多线程处理垃圾回收工作

       并发收集: GC线程和应用线程大部分时间是并发执行

  (10)如何区分垃圾

    垃圾回收的起点是一些根对象(java栈、静态变量、寄存器...)。而最简单的java栈就是java程序执行的main函数。这种回收方式,也是上面提到的“标记-清除”的回收方式。

  (11)如何处理碎片

      “复制”方式和“标记-整理”方式,都可以解决碎片的问题

  (12)如何解决同时存在的对象创建和对象回收问题
 
    垃圾回收线程是回收内存的,而程序运行线程则是消耗(或分配)内存的

     要进行垃圾回收前,一般都需要暂停整个应用(即:暂停内存的分配),然后进行垃圾回收,回收完成后再继续应用

    这种方式有一个很明显的弊端,就是当堆空间持续增大时,垃圾回收的时间也将会相应的持续增大,相应应用暂停的时间也会相应的增大

    并发垃圾回收算法


   (13)为什么要分代

    不同的对象的生命周期是不一样的。因此,不同声明周期的对象可以采取不同的收集方式,以便提高回收效率。

    分代垃圾回收采用分治的思想,进行代的划分,把不同生命周期的对象放在不同代上,不同代上采用最适合它的垃圾回收方式进行回收。

   (14)  如何分代


      虚拟机中共划分了三个代:年轻代(Young Generation)、年老代(Old Generation)和持久代(Permanent Generation)。


    年轻代:年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。

         年轻代分为三个区。一个Eden区,两个Survivor(幸存者)区

    年老代:可以认为年老代中存放的都是一些生命周期较长的对象

    持久代:用于存放静态文件,如java类、方法等。持久代对垃圾回收没有显著影响

        持久代大小通过 -XX:MaxPermSize = 进行设置

   (15)什么情况下触发垃圾回收    

    GC有两种类型:Scavenge GC 和 Full GC

        Scavenge 清除污物;打扫    

    Scavenge GC: 一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Scavenge GC

    Full GC: 对整个堆进行整理,包括Young、Tenured 和 Perm。应该尽可能减少 Full GC 的次数

    在对JVM调优的过程中,很大一部分工作就是对于 Full GC 的调节。


   (16) 有如下原因可能导致Full GC:

     年老代(Tenured)被写满
    
     持久代(Perm)被写满
    
     System.gc()被显式调用

    上一次GC之后Heap的各域分配策略动态变化

   (17) 分代垃圾回收流程示意


   (18) 选择合适的垃圾收集算法

        串行收集器: 可以使用 -XX:+UseSerialGC打开。

    并行收集器:
        对年轻代进行并行垃圾回收,因此可以减少垃圾回收时间。一般在多线程多处理器机器上使用

        使用 -XX:+UseParallelGC 打开

        可以对年老代进行并行收集, 使用 -XX:+UseParallelOldGC打开。

    使用 -XX:ParallelGCThreads = 设置并行垃圾回收的线程数。此值可以设置与机器处理器数量相等
    
        并发收集器: 此收集器适合对响应时间要求比较高的中、大规模应用。
            
        使用 -XX:+UseConcMarkSweepGC打开

         并发收集器使用处理器换来短暂的停顿时间。
        在一个N个处理器的系统上,并发收集部分使用 k/N 个可用处理器进行回收,
        一般情况下 1 <= k <= N / 4。

    (19) 浮动垃圾

    由于在应用运行的同时进行垃圾回收,所以有些垃圾可能在垃圾回收进行完成时产生,这样就造成了“Floating Garbage”

    并发收集器一般需要20%的预留空间用于这些浮动垃圾。


    (20) Concurrent Mode Failure

    并发收集器在应用运行时进行收集,所以需要保证堆在垃圾回收的这段时间有足够的空间供程序使用,否则,垃圾回收还未完成,堆空间先满了

    (21)启动并发收集器

    通过设置 -XX:CMSInitiatingOccupancyFraction = 指定还有多少剩余堆是开始执行并发收集。

    (22)小结

      串行处理器:

         -- 适用情况:数据量比较小(100M左右),单处理器下并且对相应时间无要求的应用。

         -- 缺点:只能用于小型应用。

         并行处理器:

          -- 适用情况:“对吞吐量有高要求”,多CPU,对应用过响应时间无要求的中、大型应用。举例:后台处理、科学计算。

          -- 缺点:垃圾收集过程中应用响应时间可能加长。

         并发处理器:

          -- 适用情况:“对响应时间有高要求”,多CPU,对应用响应时间有较高要求的中、大型应用。举例:Web服务器/应用服务器、电信交换、集成开发环境。


3. 堆大小设置

   (1)年轻代的设置很关键

    JVM中最大堆大小有三方面限制:相关操作系统的数据模型(32-bit 还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制。

    32位系统下,一般限制在1.5G~2G;64位操作系统对内存无限制。在Windows Server 2003系统,3.5G物理内存,JDK5.0下测试,最大可设置为1478m

   (2)  典型设置:

      java -Xmx3550m  -Xms3550m -Xmn2g  -Xss128k

    -Xmn2g: 设置年轻代大小为2G。整个堆大小=年轻代大小+年老代大小+持久代大小。
        
        持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。
        
        此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。



4. 回收器选择:

   (1) JVM给了三种选择:串行收集器、并行收集器、并发收集器,但是串行收集器只适用于小数据量的情况

       JDK5.0以后,JVM会根据当前系统配置进行判断

   (2) 吞吐量优先的并行收集器典型配置:

    并行收集器主要以到达一定的吞吐量为目标,适用于科学计算和后台处理等。

     java  -Xmx3800m  -Xms3800m  -Xmn2g  -Xss128k  -XX:+UseParallelGC  -XX:ParallelGCThreads=20

     -XX:+ParallelGCThreads=20:配置并行收集器的线程数,

    即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。

    -XX:+UseParallelOldGC:配置年老代垃圾收集方式为并行收集。JDK6.0支持对年老代并行收集

   (3)  响应时间优先的并发收集器,典型配置:

    并发收集器主要是保证系统的响应时间,减少垃圾收集时的停顿时间。适用于应用服务器、电信领域等

java  -Xmx3550m  -Xms3550  -Xmn2g  -Xss128k  -XX:ParallelGCThreads=20  -XX:+UseConcMarkSweepGC  -XX:+UseParNewGC


5.   常见配置汇总

       堆设置

           -Xms:初始堆大小

           -Xmx:最大堆大小

           -XX:NewSize=n:设置年轻代大小

           -XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5。

           -XX:MaxPermSize=n:设置持久代大小

        收集器设置

           -XX:+UseSerialGC:设置串行收集器

           -XX:+UseParallelGC:设置并行收集器

           -XX:+UseParalledlOldGC:设置并行年老代收集器

           -XX:+UseConcMarkSweepGC:设置并发收集器

        垃圾回收统计信息

           -XX:+PrintGC

           -XX:+PrintGCDetails

           -XX:+PrintGCTimeStamps

           -Xloggc:filename

         并行收集器设置

           -XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。

           -XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间

           -XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+N)

         并发收集器设置

           -XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。

           -XX:+ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数
阅读(677) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~