java的世界里young区,java young

发布时间:2022-11-23

本文目录一览:

  1. java垃圾回收那点事究竟有多少GC
  2. 如何设置Java虚拟机JVM启动内存参数
  3. Java的young代、old代以及permanent代,在哪给young代、old代以及perm
  4. java jvm 的内存到底是什么分配的,看得有点糊涂。
  5. 如何调整java虚拟机内存大小
  6. 如何监控java堆内存 virtualmachine

java垃圾回收那点事究竟有多少GC

GC不可怕,可怕的是经常FULL GC,让整个JVM停止工作进行内存回收。 常见的几种触发点如下:

  1. 持久带满了,就是Permanet Generation满了会导致FULL GC,如果GC不成功,那就报out of memory了。
  2. 旧生代满了,导致FULL GC。
  3. 新生代向S0和S1转移数据,S0和S1向旧生代转移数据,结果两边的内存设置都比较小,持续出现,会导致FULL GC。
  4. 系统直接system.gc。 常见的调整方法就是在server和client模式下调整我们的GC策略来满足特定场合的需要。一般情况下不需要做这方面的特别调优,只需要设置好持久带和新生代(S0,S1,Eden)、旧生代的内存大小即可。Java会自动回收当前的资源,如果有需要就自己调用full gc。 我们把GC分成4种类型:
  5. SerialGC
    参数:-XX:+UseSerialGC
    就是Young区和Old区都使用Serial垃圾回收算法。
  6. ParallelGC
    参数:-XX:+UseParallelGC
    • Young区:使用Parallel Scavenge回收算法
    • Old区:可以使用单线程的或者Parallel垃圾回收算法,由-XX:+UseParallelOldGC来控制。
  7. CMS
    参数:-XX:+UseConcMarkSweepGC
    • Young区:可以使用普通的或者Parallel垃圾回收算法,由参数-XX:+UseParNewGC来控制。
    • Old区:只能使用Concurrent Mark Sweep。
  8. G1
    参数:-XX:+UseG1GC
    没有Young/old区。

如何设置Java虚拟机JVM启动内存参数

  • -Xmx Java Heap最大值,默认值为物理内存的1/4,最佳设值应该视物理内存大小及计算机内其他内存开销而定。
  • -Xms Java Heap初始值,Server端JVM最好将-Xms-Xmx设为相同值,开发测试机JVM可以保留默认值。
  • -Xmn Java Heap Young区大小,不熟悉最好保留默认值。
  • -Xss 每个线程的Stack大小,不熟悉最好保留默认值。

如何设置JVM内存分配:

  1. 当在命令提示符下启动并使用JVM时(只对当前运行的类Test生效):
    java -Xmx128m -Xms64m -Xmn32m -Xss16m Test
    
  2. 当在集成开发环境下(如eclipse)启动并使用JVM时: a. 在eclipse根目录下打开eclipse.ini,默认内容为(这里设置的是运行当前开发工具的JVM内存分配)

Java的young代、old代以及permanent代,在哪给young代、old代以及perm

你的这个问题涉及面太广,需要配合图文进行理解,而且JDK4、5、6、7、8标准都不相同,而且不同厂家的JVM实现策略也各不相同。 JVM的优化没有一个固定的配置方法,根据你部署的代码特点配置优化,是一个渐进的工程。

java jvm 的内存到底是什么分配的,看得有点糊涂。

一个完整的Java程序运行过程会涉及以下内存区域:

  • 寄存器:JVM内部虚拟寄存器,存取速度非常快,程序不可控制。
  • :保存局部变量的值,包括:1. 用来保存基本数据类型的值;2. 保存类的实例,即堆区对象的引用(指针)。也可以用来保存加载方法时的帧。
  • :用来存放动态产生的数据,比如new出来的对象。注意创建出来的对象只包含属于各自的成员变量,并不包括成员方法。因为同一个类的对象拥有各自的成员变量,存储在各自的堆中,但是他们共享该类的方法,并不是每创建一个对象就把成员方法复制一次。
  • 常量池:JVM为每个已加载的类型维护一个常量池,常量池就是这个类型用到的常量的一个有序集合。包括直接常量(基本类型,String)和对其他类型、方法、字段的符号引用。池中的数据和数组一样通过索引访问。由于常量池包含了一个类型所有的对其他类型、方法、字段的符号引用,所以常量池在Java的动态链接中起了核心作用。常量池存在于堆中。
  • 代码段:用来存放从硬盘上读取的源程序代码。
  • 数据段:用来存放static定义的静态成员。

如何调整java虚拟机内存大小

在一些规模稍大的应用中,Java虚拟机(JVM)的内存设置尤为重要,想在项目中取得好的效率,GC(垃圾回收)的设置是第一步。

  • PermGen space:全称是Permanent Generation space。就是说是永久保存的区域,用于存放Class和Meta信息,Class在被Load的时候被放入该区域。
  • Heap space:存放Instance。 GC(Garbage Collection)应该不会对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。 Java Heap分为3个区:
  1. Young:保存刚实例化的对象。当该区被填满时,GC会将对象移到Old区。
  2. Old
  3. 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?

有如下原因:

  1. 程序内调用了System.gc()Runtime.gc()
  2. 一些中间件软件调用自己的GC方法,此时需要设置参数禁止这些GC。
  3. Java的Heap太小,一般默认的Heap值都很小。
  4. 频繁实例化对象,Release对象。此时尽量保存并重用对象,例如使用StringBuffer()String()。 如果你发现每次GC后,Heap的剩余空间会是总空间的50%,这表示你的Heap处于健康状态。许多Server端的Java程序每次GC后最好能有65%的剩余空间。

经验之谈:

  1. Server端JVM最好将-Xms-Xmx设为相同值。为了优化GC,最好让-Xmn值约等于-Xmx的1/3。
  2. 一个GUI程序最好是每10到20秒间运行一次GC,每次在半秒之内完成。

注意:

  1. 增加Heap的大小虽然会降低GC的频率,但也增加了每次GC的时间。并且GC运行时,所有的用户线程将暂停,也就是GC期间,Java应用程序不做任何工作。
  2. Heap大小并不决定进程的内存使用量。进程的内存使用量要大于-Xmx定义的值,因为Java为其他任务分配内存,例如每个线程的Stack等。

Stack的设定

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

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

硬件环境

硬件环境也影响GC的效率,例如机器的种类、内存、swap空间和CPU的数量。 如果你的程序需要频繁创建很多transient对象,会导致JVM频繁GC。这种情况你可以增加机器的内存,来减少Swap空间的使用。

4种GC

  1. 第一种为单线程GC,也是默认的GC,该GC适用于单CPU机器。
  2. 第二种为Throughput GC,是多线程的GC,适用于多CPU,使用大量线程的程序。与第一种GC相似,不同在于GC在收集Young区是多线程的,但在Old区和第一种一样,仍然采用单线程。参数:-XX:+UseParallelGC
  3. 第三种为Concurrent Low Pause GC,类似于第一种,适用于多CPU,并要求缩短因GC造成程序停滞的时间。这种GC可以在Old区的回收同时,运行应用程序。参数:-XX:+UseConcMarkSweepGC
  4. 第四种为Incremental Low Pause GC,适用于要求缩短因GC造成程序停滞的时间。这种GC可以在Young区回收的同时,回收一部分Old区对象。参数:-Xincgc

单文件的JVM内存进行设置

默认的Java虚拟机的大小比较小,在对大数据进行处理时Java就会报错:java.lang.OutOfMemoryError。 设置JVM内存的方法,对于单独的.class,可以用下面的方法对Test运行时的JVM内存进行设置:

java -Xms64m -Xmx256m Test
  • -Xms:设置内存初始化的大小
  • -Xmx:设置最大能够使用内存的大小(最好不要超过物理内存大小)

Tomcat启动JVM内存设置

Linux: 在/usr/local/apache-tomcat-5.5.23/bin目录下的catalina.sh添加:

JAVA_OPTS='-Xms512m -Xmx1024m'

Windows: 在catalina.bat最前面加入:

set JAVA_OPTS=-Xms128m -Xmx350m

如果用startup.bat启动Tomcat,OK设置生效。但是如果不是执行startup.bat启动Tomcat而是利用Windows的系统服务启动Tomcat服务,上面的设置就不生效了。解决办法: 修改注册表:

HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Tomcat Service Manager\Tomcat5\Parameters\JavaOptions

原值为:

-Dcatalina.home="C:\ApacheGroup\Tomcat 5.0"
-Djava.endorsed.dirs="C:\ApacheGroup\Tomcat 5.0\common\endorsed"
-Xrs

加入:

-Xms300m -Xmx350m

重启Tomcat服务,设置生效。

Weblogic启动JVM内存设置

在Weblogic中,可以在startweblogic.cmd中对每个domain虚拟内存的大小进行设置,默认的设置是在commEnv.cmd里面。

JBoss

默认可以使用的内存为64MB:

$JBOSSDIR$/bin/run.config
JAVA_OPTS = "-server -Xms128 -Xmx512"

Eclipse

在所在目录下,键入:

eclipse.exe -vmargs -Xms256m -Xmx512m

256m表示JVM堆内存最小值,512m表示JVM堆内存最大。

Websphere

进入控制台去设置:应用程序服务器 server1 进程定义 Java 虚拟机。

如何监控java堆内存 virtualmachine

分代收集(Generational Collecting)

基于对对象生命周期分析后得出的垃圾回收算法,把对象分为年轻代、年老代、持久代,对不同生命周期的对象使用不同的算法进行回收。现在的垃圾回收器(从J2SE1.2开始)都是使用此算法。 Sun JVM内存区域分布图:

  1. Young(年轻代)
    Young被划分为三个区间,Eden区和两个大小严格相同的Survivor区,其中Survivor区,在某一时刻只有其中一个是被使用的,另外一个留做垃圾收集时复制对象用。在Young区间变满的时候,Minor GC就会将存活的对象移到空闲的Survivor区中,根据JVM的策略,在经过几次Minor GC后,任然存活于Survivor区的对象将被移动到Tenured中。
  2. Tenured(年老代)
    Tenured主要保存生命周期长的对象,一般是一些老的对象,当一些对象在Young复制转移一定的次数以后,对象就会被转移到Tenured。一般如果系统中用了application级别的缓存,缓存中的对象往往会被转移到这一区间。
  3. Perm(持久代)
    Perm主要保存class、method、filed等对象,这部分的空间一般不会溢出,除非一次性加载了很多的类。不过在涉及到应用服务器的热部署时,有时候会遇到java.lang.OutOfMemoryError: PermGen space的错误,造成这个错误的很大原因就有可能是每次热部署后,旧的class没有被卸载掉,这样就造成了大量的class对象保存在了Perm中。这种情况下一般重新启动应用服务器可以解决问题,或者通过-XX:MaxPermSize=N将持久代大小设大点。

GC类型

大略上分以下2种:

  1. Minor GC
    一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Minor GC在Eden区清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后再整理Survivor的两个区。
  2. Full GC
    对整个堆进行整理,包括Young、Tenured以及Perm。Full GC比Minor GC要慢,因此应该尽可能减少Full GC。以下几种原因可能导致Full GC:
    • Tenured或Perm被写满
    • System.gc被显示调用
    • 上一次GC后堆空间分配策略动态调整

JVM调优参数

JVM提供了相应的参数来对内存大小、垃圾回收算法进行配置。

Non-standard Java HotSpot VM Options

我在32位Windows Server 2003系统8GB物理内存,JDK1.6下测试,最大可设置为1536M,再多JVM就跑不起来了。

  • -Xms1536M:设置JVM启动后堆的初始内存(这里配置的JVM堆空间只是Young与Tenured)
  • -Xmx1536M:设置JVM启动后堆的最大内存,一般在生产环境中把这两个参数设为相同值,避免在“上一次GC后堆空间分配策略动态调整”而引起Full GC
  • -Xss1M:设置每个线程的Java栈大小
  • -XX:NewRatio=2:设置Tenured和Young的比值为2:1,这样Eden+2*Survivor=1/3堆内存
  • -XX:SurvivorRatio=8:设置Eden和一个Survivor的比值为8:1,这样一个Survivor就占Young区的1/10
  • -XX:PermSize=64M:设置持久代初始内存
  • -XX:MaxPermSize=128M:设置持久代最大内存

垃圾收集器

JVM给了三种选择:串行收集器、并行收集器、并发收集器。串行收集器对于处理大数据量的情况时性能太低,所以一般选择使用并行收集器和并发收集器。J2SE5.0以后JVM会根据当前系统配置进行判断(机器配置只要有2个CPU和至少2GB的物理内存JVM将自动以-server模式运行)

  1. 吞吐量优先的并行收集器,通过-XX:+UseParallelGC指定
  2. 响应时间优先的并发收集器,主要是保证系统的响应时间,减少垃圾收集时的停顿时间。通过-XX:+UseConcMarkSweepGC指定。由于CMS GC是和应用并发执行的,因此需要耗费更多的CPU资源。

Sun JDK自带的图形监控和管理工具jconsole

通过Sun JDK自带的一个图形监控和管理工具jconsole能很容易的看到当前虚拟机中的内存状态,我使用的JDK版本是jdk1.6.0_18,这个工具从jdk1.5就有了。