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

点击进入_更多_Java千百问

1、java内存如何优化

了解jvm内存管理看这里:jvm是如何管理内存的

了解堆内存看这里:java堆内存是什么样的

java内存的优化主要是通过合理的控制GC来实现,主要原则:

1. 不能只看操作系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用情况(因为GC过后这个值是不会变化的)。

2. 使用JDK提供的内存查看工具,比如JConsole和Java 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来设置。

时间: 2024-12-20 18:02:30

Java千百问_07JVM架构(016)_java内存如何优化的相关文章

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

点击进入_更多_Java千百问 1.什么是内存模型 Java平台自动集成了线程以及多处理器技术,这种集成程度比Java以前诞生的计算机语言要厉害很多.Java针对多种异构平台的独立性,使得多线程技术也具有了开拓性的一面. 我们有时候在Java开发中,对于同步和线程安全要求很严格的程序时,往往容易混淆的一个概念就是内存模型.那究竟什么是内存模型呢? 内存模型描述了程序中各个变量(实例域.静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存.从内存中取出变量这样的底层细节. Java

Java千百问_07JVM架构(011)_java垃圾回收都有哪些方式

点击进入_更多_Java千百问 1.java垃圾回收都有哪些方式 所谓垃圾回收方式,是指JVM提供的几种不同的垃圾回收器,不同的垃圾回收器进行垃圾回收时采用不同的方式.当然,总体原则遵循java垃圾回收机制. 了解java内存模型看这里:java内存模型是什么样的 了解堆内存看这里:java堆内存是什么样的 了解java垃圾回收机制看这里:java垃圾回收机制是什么 每种方式都有自己的优势与劣势.我们编程的时候可以通过向JVM传递参数来选择垃圾回收器.不同的垃圾回收期有大的不同,可以为我们提供完

Java千百问_07JVM架构(013)_java什么情况会内存溢出

点击进入_更多_Java千百问 1.Java堆什么情况会溢出 所有对象的实例都在Java堆上分配内存,堆大小由-Xmx和-Xms来调节,如果程序使用的内存超过了堆最大内存(-Xmx),则会溢出Java heap space. 了解java内存模型看这里:java内存模型是什么样的 了解堆内存看这里:java堆内存是什么样的 了解java垃圾回收机制看这里:java垃圾回收机制是什么 实例: public class HeapOOM { static class OOMObject{} /** *

Java千百问_07JVM架构(008)_java垃圾回收机制是什么

点击进入_更多_Java千百问 1.如何判断垃圾对象 垃圾收集的第一步就是先需要算法来标记哪些是垃圾,然后再对垃圾进行处理.通常的编程语言都会用以下算法之一进行判断: 引用计数(ReferenceCounting)算法 这种方法比较简单直观,核心思路是,给每个对象添加一个被引用计数器,被引用时+1,引用失效-1,等于0时就表示该对象没有被引用,可以被回收. FlashPlayer/Python使用该算法,简单高效.但是,Java/C#并不采用该算法,因为该算法没有解决对象相互引用的问题,即:当两

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

点击进入_更多_Java千百问 1.java堆和栈有什么区别 了解jvm内存管理看这里:jvm是如何管理内存的 在<jvm是如何管理内存的>这篇文章中,已经对PC寄存器(计数器 pc registers).方法区(method area).本地方法栈(native method stacks).栈(stacks).堆(heap)内存区域做了介绍,其中栈(stacks).堆(heap)是java内存管理中非常重要的两个部分,具体区别如下: 2.基本数据类型储存在栈中吗 基本数据类型由于长度固定,

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

点击进入_更多_Java千百问 1.如何监控jvm的运行情况 了解jvm内存模型看这里:java内存模型是什么样的 了解jvm内存管理看这里:jvm是如何管理内存的 了解jvm垃圾回收机制看这里:java垃圾回收机制是什么 了解jvm内存优化看这里:java内存如何优化 我们通常使用Jdk工具来监控jvm的运行情况,当然目前有很多第三方产品是通过jdk提供的api来组织数据进行监控的.具体来说有如下监控软件: Jconsole jdk自带,功能简单,但是可以在系统有一定负荷的情况下使用.对垃圾回

Java千百问_07JVM架构(002)_jvm实例的结构是什么样的

点击进入_更多_Java千百问 1.jvm实例的结构是什么样的 在Java虚拟机规范中,一个虚拟机实例的行为主要组成部分为:子系统.内存区域.数据类型和指令. 这些组件描述了JVM内部的一个抽象结构.与其说这些组成部分的目的是进行JVM内部结构的一种支配,不如说是提供一种对外部行为的严格定义,该规范定义了这些抽象组成部分的相互作用,以及Java虚拟机执行所需要的行为. 了解jvm内存管理看这里:java内存模型是什么样的 下图描述了JVM实例的一个内部结构,其中主要包括主要的子系统.内存区域.

Java千百问_07JVM架构(012)_fullGC、minorGC、magorGC有什么区别

点击进入_更多_Java千百问 1.fullGC.minorGC.magorGC有什么区别 fullGC.minorGC.magorGC还有youngGC是Java垃圾处理机制(GC)的名词,区分这几个概念非常简单: 老生代进行一次垃圾清理,被称为fullGC或者magorGC. 新生代进行一次垃圾清理,被称为youngGC或者minorGC. 了解java垃圾回收机制看这里:java垃圾回收机制是什么 解释完毕,不过要提一下的是,我们在JVM优化过程中的一个原则就是: 降低youngGC的频率

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

点击进入_更多_Java千百问 1.运行时常量池是什么 运行时常量池(Runtime Constant Pool),它是方法区的一部分.Class文件中除了有类的版本.字段.方法.接口等描述等信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放到常量池中. 了解java内存管理看这里:jvm是如何管理内存的 如图: 运行时常量是相对于常量来说的,它具备一个重要特征是:动态性.当然,值相同的动态常量与我们通常说