07JVM架构(016)_java内存如何优化

转载 2016年08月30日 15:42:43

1、java内存如何优化

了解jvm内存管理看这里:jvm是如何管理内存的 
了解堆内存看这里:java堆内存是什么样的 
java内存的优化主要是通过合理的控制GC来实现,主要原则: 
1. 不能只看操作系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用情况(因为GC过后这个值是不会变化的)。 
2. 使用JDK提供的内存查看工具,比如JConsoleJava VisualVM。 
3. 优化内存主要的目的是降低youngGC的频率减少fullGC的次数 ,过多的youngGC和fullGC是会占用很多的系统资源(主要是CPU),影响系统的吞吐量

这里,影响内存效率最关键的就是:fullGC,因为它会对整个堆内存进行整理,占用大量的资源。

2、FullGC何时发生

fullGC作为java内存管理的关键,它的触发时机我们一定要掌握,有4种情况会发生fullGC:

  1. 旧生代空间不足 
    调优时尽量让对象在新生代GC时被回收、让对象在新生代多存活一段时间不要创建过大的对象及数组避免直接在旧生代创建对象。

  2. Pemanet Generation空间不足 
    增大Perm Gen空间,避免太多静态对象。了解内存溢出看这里:java什么情况会内存溢出

  3. GC后晋升到老生代的平均大小大于老生代剩余空间 
    控制好新生代和旧生代的比例

  4. System.gc()被显示调用 
    垃圾回收不要手动触发,尽量依靠JVM自身的机制。

3、GC有哪些优化手段

GC调优手段主要是通过控制堆内存的各个部分比例,以及根据不同场景采用不同的GC策略来实现。下面分别来看:

通过控制堆内存比例优化GC

  1. 新生代设置过小 
    一是新生代容易占满,导致新生代GC(youngGC)次数非常频繁,增大系统消耗; 
    二是大对象直接进入老生代,占据了老生代剩余空间,诱发fullGC。 
    了解youngGC和FullGC看这里:fullGC、minorGC、magorGC有什么区别
  2. 新生代设置过大 
    一是新生代设置过大会导致旧生代过小(堆总量一定),从而诱发fullGC。 
    二是新生代GC耗时大幅度增加。 
    一般说来新生代占整个堆1/3比较合适。

  3. Survivor设置过小 
    新生代中根据优化复制算法,如果Survivor区(S0,S1)太小,会导致对象从eden区直接到达旧生代,降低了在新生代的存活时间。一般来说Eden:S0:S1为8:1:1是比较合理的。 
    了解新生代复制算法看这里:什么是新生代的复制算法

  4. Survivor设置过大 
    若Survivor区过大,则eden区会过小,eden区容易达到阈值导致新生代GC频率增加

  5. 新生代对象存活时间过短 
    通过-XX:MaxTenuringThreshold=n来控制新生代存活时间,如果存活时间过短,则对象会很快进入老生代,导致fullGC。所以要尽量让不常用对象在新生代被回收

通过GC策略优化GC

新生代和旧生代都有很多种GC策略和组合搭配,选择这些策略对于我们这些开发人员是个难题,默认情况下JVM会自动调整新生代与老生代的比例、Eden区与Suvivor区的比例来达到性能目标,JVM提供两种较为简单的GC策略的设置方式:

  1. 吞吐量优先 
    JVM以吞吐量为指标,自行选择相应的GC策略及 控制堆内存的大小比例,来达到吞吐量指标。一次fullGC时间占总可用时间的比例,如果GC时间过长,会相应调整空间的大小(花费在GC上的时间比例不超过1 / (1 + n))。 
    通过-XX:GCTimeRatio=n来设置。

  2. 暂停时间优先 
    JVM以暂停时间为指标,自行选择相应的GC策略及控制堆内存的大小比例,尽量保证每次GC造成的应用停止时间都在指定的数值范围内完成。如果时间过长,会相应调整空间的大小(单位是毫秒)。 
    通过-XX:MaxGCPauseMillis=n来设置。

相关文章推荐

Java千百问_07JVM架构(016)_java内存如何优化

点击进入_更多_Java千百问1、java内存如何优化了解jvm内存管理看这里:jvm是如何管理内存的 了解堆内存看这里:java堆内存是什么样的 java内存的优化主要是通过合理的控制GC来实现...

Java千百问_07JVM架构(005)_显示内存管理有什么弊端

点击进入_更多_Java千百问1、显示内存管理有什么弊端手动内存管理一般被称为显示内存管理,显示内存管理经常发生两种情况: 引用悬挂 当一个被某个引用变量正在使用的内存空间,在重新分配过程中被释放掉...

Java千百问_07JVM架构(003)_内存分配有哪些策略

点击进入_更多_Java千百问1、内存分配有哪些策略我们从编译原理讲起,不同的开发环境、开发语言都会有不同的策略。一般来说,程序运行时有三种内存分配策略:静态的、栈式的、堆式的 静态存储 是指在编译...

Java千百问_07JVM架构(007)_java堆内存是什么样的

点击进入_更多_Java千百问1.堆内存是什么样的了解jvm实例模型看这里:jvm实例的结构是什么样的 了解java内存框架看这里:jvm是如何管理内存的 了解堆栈的区别看这里:java堆和栈有什...

Java千百问_07JVM架构(001)_java内存模型是什么样的

点击进入_更多_Java千百问1、什么是内存模型  Java平台自动集成了线程以及多处理器技术,这种集成程度比Java以前诞生的计算机语言要厉害很多。Java针对多种异构平台的独立性,使得多线程技术也...

Java千百问_07JVM架构(009)_什么是新生代的复制算法

所谓复制算法(Copying),即将内存平均分成A区、B区两块,进行复制+清除垃圾的操作,算法图解如下:算法过程: 新生对象被分配到A块中未使用的内存当中。当A块的内存用完了, 把A块的存活对象复制到...

Java千百问_07JVM架构(010)_什么是老生代的标记算法

所谓标记算法(Mark),分为多种,最简单直观的即标记-清除算法(Mark-Sweep)。即将认定为可回收的内存做一个标记,然后统一将被标记的清理,算法图解如下:算法过程: 1. 先判定对象是否可回...

Java千百问_07JVM架构(019)_运行时常量池是什么

点击进入_更多_Java千百问1、运行时常量池是什么运行时常量池(Runtime Constant Pool),它是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述等信息外,还有...

Java千百问_07JVM架构(006)_java堆和栈有什么区别

在《jvm是如何管理内存的》这篇文章中,已经对PC寄存器(计数器 pc registers)、方法区(method area)、本地方法栈(native method stacks)、栈(stacks...

Java千百问_07JVM架构(018)_如何监控jvm的运行情况

点击进入_更多_Java千百问1、如何监控jvm的运行情况了解jvm内存模型看这里:java内存模型是什么样的 了解jvm内存管理看这里:jvm是如何管理内存的 了解jvm垃圾回收机制看这里:ja...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:07JVM架构(016)_java内存如何优化
举报原因:
原因补充:

(最多只允许输入30个字)