JVM内存的调优

标签: jvm 内存 | 发表时间:2012-01-03 23:08 | 作者:
出处:http://www.iteye.com

一 .JVM 内存的设置的原理

默认的 java 虚拟机的大小比较小,在对大数据进行处理时 java 就会报错: java.lang.OutOfMemoryError 。设置 jvm 内存的方法,对于单独的 .class ,可以用下面的方法对 Test 运行时的 jvm 内存进行设置。
java -Xms64m -Xmx256m Test
-Xms 是设置内存初始化的大小
-Xmx 是设置最大能够使用内存的大小(最好不要超过物理内存大小)
在 weblogic 中,可以在 startweblogic.cmd 中对每个 domain 虚拟内存的大小进行设置,默认的设置是在 commEnv.cmd 里面。

-vmargs
-Xms128M
-Xmx512M
-XX:PermSize=64M
-XX:MaxPermSize=128M

下面是这几个设置的一些背景知识:

  • 堆(Heap)和非堆(Non-heap)内存
    按照官 方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。可以看出JVM主要管理两种类型的内存:堆和非堆。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给 自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法 的代码都在非堆内存中。
  • 堆内存分配
    JVM初始分配的内存由-Xms 指定,默认是物理内存的1/64;JVM最 大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时, JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。
  • 非堆内存分配
    JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。
  • JVM内存限制(最大值)
    首先JVM内存首 先受限于实际的最大物理内存,假设物理内存无限 大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是 2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了
  • JVM 内存的调优

    1. Heap 设定与垃圾回收 Java Heap 分为 3 个区, Young , Old 和 Permanent 。 Young 保存刚实例化的对象。当该区被填满时, GC 会将对象移到 Old 区。 Permanent 区则负责保存反射对象,本文不讨论该区。 JVM 的 Heap 分配可以使用 -X 参数设定,

    -Xms

    初始 Heap 大小

    -Xmx

    java heap 最大值

    -Xmn

    young generation 的 heap 大小

    JVM 有 2 个 GC 线程。第一个线程负责回收 Heap 的 Young 区。第二个线程在 Heap 不足时,遍历 Heap ,将 Young 区升级为 Older 区。 Older 区的大小等于 -Xmx 减去 -Xmn ,不能将 -Xms 的值设的过大,因为第二个线程被迫运行会降低 JVM 的性能。

    为什么一些程序频繁发生 GC ?有如下原因:

    l         程序内调用了 System.gc() 或 Runtime.gc() 。

    l         一些中间件软件调用自己的 GC 方法,此时需要设置参数禁止这些 GC 。

    l         Java 的 Heap 太小,一般默认的 Heap 值都很小。

    l         频繁实例化对象, Release 对象。此时尽量保存并重用对象,例如使用 StringBuffer() 和 String() 。

             如果你发现每次 GC 后, Heap 的剩余空间会是总空间的 50% ,这表示你的 Heap 处于健康状态。许多 Server 端的 Java 程序每次 GC 后最好能有 65% 的剩余空间。经验之谈:

    1 . Server 端 JVM 最好将 -Xms 和 -Xmx 设为相同值。为了优化 GC ,最好让 -Xmn 值约等于 -Xmx 的 1/3[2] 。

    2 .一个 GUI 程序最好是每 10 到 20 秒间运行一次 GC ,每次在半秒之内完成 [2] 。

    注意:

    1 .增加 Heap 的大小虽然会降低 GC 的频率,但也增加了每次 GC 的时间。并且 GC 运行时,所有的用户线程将暂停,也就是 GC 期间, Java 应用程序不做任何工作。

    2 . Heap 大小并不决定进程的内存使用量。进程的内存使用量要大于 -Xmx 定义的值,因为 Java 为其他任务分配内存,例如每个线程的 Stack 等。

    2 . Stack 的设定

    每个线程都有他自己的 Stack 。

    -Xss

    每个线程的 Stack 大小

    Stack 的大小限制着线程的数量。如果 Stack 过大就好导致内存溢漏。 -Xss 参数决定 Stack 大小,例如 -Xss1024K 。如果 Stack 太小,也会导致 Stack 溢漏。

    3 .硬件环境

    硬件环境也影响 GC 的效率,例如机器的种类,内存, swap 空间,和 CPU 的数量。

    如果你的程序需要频繁创建很多 transient 对象,会导致 JVM 频繁 GC 。这种情况你可以增加机器的内存,来减少 Swap 空间的使用 [2] 。

    4 . 4 种 GC

    第一种为单线程 GC ,也是默认的 GC 。,该 GC 适用于单 CPU 机器。

    第二种为 Throughput GC ,是多线程的 GC ,适用于多 CPU ,使用大量线程的程序。第二种 GC 与第一种 GC 相似,不同在于 GC 在收集 Young 区是多线程的,但在 Old 区和第一种一样,仍然采用单线程。 -XX:+UseParallelGC 参数启动该 GC 。

    第三种为 Concurrent Low Pause GC ,类似于第一种,适用于多 CPU ,并要求缩短因 GC 造成程序停滞的时间。这种 GC 可以在 Old 区的回收同时,运行应用程序。 -XX:+UseConcMarkSweepGC 参数启动该 GC 。

    第四种为 Incremental Low Pause GC ,适用于要求缩短因 GC 造成程序停滞的时间。这种 GC 可以在 Young 区回收的同时,回收一部分 Old 区对象。 -Xincgc 参数启动该 GC 。



    已有 0 人发表留言,猛击->> 这里<<-参与讨论


    ITeye推荐



    相关 [jvm 内存] 推荐:

    JVM内存分配

    - - 移动开发 - ITeye博客
    计算机内存,它算是CPU与计算机打交道最频繁的区域,所有数据都是先经过硬盘至内存,然后由CPU再从内存中获取数据进行处理,又将数据保存到内存,通过分页或分片技术将内存中的数据再flush至硬盘. 那JVM的内存结构到底是如何呢. JVM做为一个运行在操作系统上,但又独立于os运行的平台,它的内存至少应该包括象寄存器、堆栈等区域.

    jvm内存映像分析

    - - ITeye博客
         jdk自带的jmap就是java内存映像工具,可以用于上生成堆转储快照:. 在eclipse中启动一个java类,打开jdk安装目录下的C:\Program Files\Java\jdk1.6.0_11\bin目录,双击jconsole.exe,显示连接窗口:.  ,单击pid为6920的选项,点连接进入,可以看到jvm运行时的多种参数,.

    JVM内存的调优

    - - ITeye博客
    默认的 java 虚拟机的大小比较小,在对大数据进行处理时 java 就会报错: java.lang.OutOfMemoryError. 设置 jvm 内存的方法,对于单独的 .class ,可以用下面的方法对 Test 运行时的 jvm 内存进行设置. -Xms 是设置内存初始化的大小. -Xmx 是设置最大能够使用内存的大小(最好不要超过物理内存大小).

    MAT JVM内存分析

    - - 开源软件 - ITeye博客
    我们使用的是 Eclipse Memory Analyzer V0.8,Sun JDK 6. 和其他插件的安装非常类似,MAT 支持两种安装方式,一种是“单机版“的,也就是说用户不必安装 Eclipse IDE 环境,MAT 作为一个独立的 Eclipse RCP 应用运行;另一种是”集成版“的,也就是说 MAT 也可以作为 Eclipse IDE 的一部分,和现有的开发平台集成.

    [译] HotSpot JVM 内存管理

    - - IT瘾-dev
    HotSpot JVM 内存管理. 更新时间:2018-03-28. 关于 JVM 内存管理或者说垃圾收集,大家可能看过很多的文章了,笔者准备给大家总结下. 这算是系列的第一篇,接下来一段时间会持续更新. 本文主要是翻译《 Memory Management in the Java HotSpot Virtual Machine》白皮书的前四章内容,这是 2006 的老文章了,当年发布这篇文章的还是 Sun Microsystems,以后应该会越来越少人记得这家曾经无比伟大的公司了.

    【JVM】HotSpot JVM内存管理和GC策略总结

    - - ITeye博客
    JVM的相关知识是学习java高级特性必须要去深入学习的. 平时也有一些学习和实践,不过总结比较少. 今天有时间总结一下最基础的内存模型和GC策略的知识,在此记录一下. hotspot jvm内存模型. hotspot的内存模型很多地方都有类似总结,我也简单总结了一下,大概可以用下图表示:. 1.线程栈:线程创建是会为每个线程创建一个线程栈,线程栈里面会为每个方法调用创建一个栈帧.

    java 内存移到堆外!!! Jvm gcih 淘宝优化JVM实践

    - - CSDN博客互联网推荐文章
    出自Jvm  GC-Invisible Heap. GC-Invisible Heap,简称GCIH,是一种将Java对象从Java堆内移动到堆外,并且可以在JVM间共享这些对象的技术. GCIH顾名思义就是GC访问不到的堆,它是对JVM内存管理机制的一个有益的补充. 在某些特殊的应用中有大量生命周期很长的对象,在应用运行的整个过程中它们都存在,不需要被GC回收.

    JVM内存管理学习总结(一)

    - - CSDN博客互联网推荐文章
    I.JVM进程的生命周期. JVM实例的生命周期和java程序的生命周期保持一致,即一个新的程序启动则产生一个新的JVM进程实例,程序结束则JVM进程实例伴随着消失. 那么程序启动和程序终止就是JVM实例生命周期的两个边界,两个边界点可以这么理解:一个拥有程序入口(main函数)的class在执行main方法时,相应的JVM就被创建了(即JVM生命周期的起点),当由此main函数启动的所有非守护线程都终止时,JVM即退出(JVM实例生命周期的终点).

    在JVM发生FGC前后dump内存

    - - 互联网 - ITeye博客
    有时候web应用经常会发生FGC,我们想知道FGC把那些对象给回收了,思路很简单就是看看FGC之前内存中有那些实例,FGC之后内存中又有那些实例,通过前后的比较,我们就能很容易知道FGC回收了那些实例,当然我们可以手工去dump内存,在FGC发生之前dump一下内存,再在FGC发生之后dump一下内存,但是这dump的时间点不好把握,能否让JVM自动去dump就更好了.

    JVM实用参数(四)内存调优

    - - Java - 编程语言 - ITeye博客
    理想的情况下,一个Java程序使用JVM的默认设置也可以运行得很好,所以一般来说,没有必要设置任何JVM参数. 然而,由于一些性能问题(很不幸的是,这些问题经常出现),一些相关的JVM参数知识会是我们工作中得好伙伴. 在这篇文章中,我们将介绍一些关于JVM内存管理的参数. 知道并理解这些参数,将对开发者和运维人员很有帮助.