minor gc major.minor版本52 gc full gc什么时候发生

主题信息(必填)
主题描述(最多限制在50个字符)
申请人信息(必填)
申请信息已提交审核,请注意查收邮件,我们会尽快给您反馈。
如有疑问,请联系
CSDN &《程序员》编辑/记者,投稿&纠错等事宜请致邮
你只管努力,剩下的交给时光!
如今的编程是一场程序员和上帝的竞赛,程序员要开发出更大更好、傻瓜都会用到软件。而上帝在努力创造出更大更傻的傻瓜。目前为止,上帝是赢的。个人网站:。个人QQ群:、
个人大数据技术博客:
Minor GC、Major GC和Full GC之间的区别Major GC和Full GC的区别是什么?触发条件呢? - 知乎292被浏览19497分享邀请回答21726 条评论分享收藏感谢收起3417 条评论分享收藏感谢收起查看更多回答1 个回答被折叠()之前的文章尤其是讲解GC的时候提到了很多的概念,比如内存溢出和内存泄露、并行与并发、Client模式和Server模式、Minor GC和Full GC,本文详细讲解下这些概念的区别。
内存溢出和内存泄露的区别
1、内存溢出
内存溢出指的是程序在申请内存的时候,没有足够大的空间可以分配了。
2、内存泄露
内存泄露指的是程序在申请内存之后,没有办法释放掉已经申请到内存,它始终占用着内存,即被分配的对象可达但无用。内存泄露一般都是因为内存中有一块很大的对象,但是无法释放。
从定义上可以看出,内存泄露终将导致内存溢出。
注意,定位虚拟机问题内存问题的时候第一步就是要判断到底是内存溢出还是内存泄露,前者好判断,跟踪堆栈信息就可以了;后者比较复杂一点,一般都是老年代中的大对象没释放掉,要通过各种办法找出老年代中的大对象没有被释放的原因。
并行和并发的区别
这两个名词都是并发编程中的概念,在谈论垃圾收集器的上下文语境中,可以这么理解这两个名词:
1、并行Parallel
多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态
2、并发Concurrent
指用户线程与垃圾收集线程同时执行(但并不一定是并行的,可能会交替执行),用户程序在继续运行,而垃圾收集程序运行于另一个CPU上
Minor GC和Full GC的区别
1、新生代GC(Minor GC)
指发生在新生代的垃圾收集动作,因为大多数Java对象存活率都不高,所以Minor GC非常频繁,一般回收速度也比较快
2、老年代GC(Major GC/Full GC)
指发生在老年代的垃圾收集动作,出现了Major GC,经常会伴随至少一次的Minor GC(但并不是绝对的)。Major GC的速度一般要比Minor GC慢上10倍以上
Client模式和Server模式的区别
部分商用虚拟机中,Java程序最初是通过解释器对.class文件进行解释执行的,当虚拟机发现某个方法或代码块运行地特别频繁的时候,就会把这些代码认定为热点代码Hot Spot Code(这也是我们使用的虚拟机HotSpot名称的由来)。为了提高热点代码的执行效率,在运行时,虚拟机将会把这些代码编译成与本地平台相关的机器码,并进行各种层次的优化,完成这个任务的编译器叫做即时编译器(Just In Time Compiler,即JIT编译器)。JIT编译器并不是虚拟机必需的部分,Java虚拟机规范并没有要求要有JIT编译器的存在,更没有限定或指导JIT编译器应该如何去实现。但是,JIT编译器性能的好坏、代码优化程度的高低却是衡量一款商用虚拟机优秀与否的最关键指标之一。
解释器和编译器其实和编译器各有优势:
1、当程序需要迅速启动和执行的时候,解释器可以先发挥作用,省去编译的时间,立即执行
2、在程序运行后,随着时间的推移,编译器逐渐发挥作用,把越来越多的代码编译成本地代码之后,可以获取更高的执行效率
我们使用的HotSpot中内置了两个JIT编译器,即C1编译器和C2编译器,默认采用的是解释器和一个编辑器配合的方式进行工作。HotSpot在启动的时候会根据自身版本以及宿主机器的硬件性能自动选择运行模式,比如会检测宿主机器是否为服务器、比如J2SE会检测主机是否有至少2个CPU和至少2GB的内存。
1、如果是,则虚拟机会以Server模式运行,该模式与C2编译器共同运行,更注重编译的质量,启动速度慢,但是运行效率高,适合用在服务器环境下,针对生产环境进行了优化
2、如果不是,则虚拟机会以Client模式运行,该模式与C1编译器共同运行,更注重编译的速度,启动速度快,更适合用在客户端的版本下,针对GUI进行了优化
有两种方法查看虚拟机是运行在Client模式下还是Server模式下:
1、在程序命令行运行&java -version&命令,查看的是你本地安装的虚拟机是信息
2、比如我们用Eclipse或者MyEclipse运行程序,一般使用的都是工具自带的JRE,虚拟机并不是本地安装的虚拟机。这时候怎么办呢,可以通过在程序中运行下面的语句来查看虚拟机信息
System.out.println(System.getProperty("java.vm.name"));
我这里的运行结果是
Java HotSpot(TM) 64-Bit Server VM
当然要改变虚拟机运行的模式也可以,只需要改jvm.cfg就可以了。我们可以从以下几个地方找到jvm.cfg:
1、32位的JDK的文件路径是 &JAVA_HOME/jre/lib/i386/jvm.cfg
2、64位的JDK的文件路径是 &JAVA_HOME/jre/lib/amd64/jvm.cfg
3、MyEclipse在 .../Common/binary/com.sun.java.jdk.win32.x86_64_1.6.0.013/jre/lib/amd64/jvm.cfg
目前64位只支持Server模式,文件内容都是一样的,上面的注释不去管它,剩下的就是这些:
-server KNOWN
-client IGNORE
-hotspot ALIASED_TO -server
-classic WARN
-native ERROR
-green ERROR
由于我的电脑装的是64位JDK,所以是&-client INGORE&。同时支持Server模式和Client模式的,应该是&-server KNOWN&和&-client KNOWN&,一般只需要变更这两个配置的先后顺序即可,但是前提是JAVA_HOME/jre/bin目录下同时存在server和client两个文件夹,分别对应着各自的虚拟机,缺少一个,切换后就会报错。
阅读(...) 评论()Java垃圾回收之Minor GC和Major GC
时间: 18:26:22
&&&& 阅读:685
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&JAVA堆的描述如下:
&  内存由Perm和Heap组成。其中Heap = {Old + NEW = { Eden , from, to } }
  JVM内存模型中分两大块:
  NEW Generation:程序新创建的对象都是从新生代分配内存,新生代由Eden Space和两块相同大小的Survivor Space(通常又称S0和S1或From和To)构成,可通过-Xmn参数来指定新生代的大小,也可以通过-XX:SurvivorRation来调整Eden Space及Survivor Space的大小。
一块是 NEW Generation, 另一块是Old Generation. 在New Generation中,有一个叫Eden的空间,主要是用来存放新生的对象,还有两个Survivor Spaces(from,to), 它们用来存放每次垃圾回收后存活下来的对象。在Old Generation中,主要存放应用程序中生命周期长的内存对象,还有个Permanent Generation,主要用来放JVM自己的反射对象,比如类对象和方法对象等。
&  垃圾回收描述:
  在New Generation块中,垃圾回收一般用Copying的算法,速度快。每次GC的时候,存活下来的对象首先由Eden拷贝到某个Survivor Space, 当Survivor Space空间满了后, 剩下的live对象就被直接拷贝到Old Generation中去。因此,每次GC后,Eden内存块会被清空。在Old Generation块中,垃圾回收一般用mark-compact的算法,速度慢些,但减少内存要求。
  垃圾回收分多级,0级为全部(Full)的垃圾回收,会回收OLD段中的垃圾;1级或以上为部分垃圾回收,只会回收NEW中的垃圾,内存溢出通常发生于OLD段或Perm段垃圾回收后,仍然无内存空间容纳新的Java对象的情况。
现在收集器都是采用分代收集算法,堆被划分为新生代和老年代。新生代主要存储新创建的对象和尚未进入老年代的对象。老年代存储经过多次新生代GC(Minor GC)任然存活的对象。
  Minor GC:即新生代GC,指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快。
  老生代:用于存放经过多次新生代GC任然存活的对象,例如缓存对象,新建的对象也有可能直接进入老年代,主要有两种情况:①大对象,可通过启动参数设置-XX:PretenureSizeThreshold=1024(单位为字节,默认为0)来代表超过多大时就不在新生代分配,而是直接在老年代分配。②大的数组对象,切数组中无引用外部对象。老年代所占的内存大小为-Xmx对应的值减去-Xmn对应的值。
  Major GC &/ Full GC:老年代GC,指发生在老年代的GC,出现了Major GC,经常会伴随至少一次的Minor GC(但非绝对的,在 ParallelScavenge 收集器的收集策略里就有直接进行 Major GC的策略选择过程) 。MajorGC 的速度一般会比Minor GC慢10倍以上。
  当一个URL被访问时,内存申请过程如下:
A. JVM会试图为相关Java对象在Eden中初始化一块内存区域
B. 当Eden空间足够时,内存申请结束。否则到下一步
C. JVM试图释放在Eden中所有不活跃的对象(这属于1或更高级的垃圾回收), 释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区
D. Survivor区被用来作为Eden及OLD的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区
E. 当OLD区空间不够时,JVM会在OLD区进行完全的垃圾收集(0级)
F. 完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现&out of memory错误&
JVM调优建议:
ms/mx:定义YOUNG+OLD段的总尺寸,ms为JVM启动时YOUNG+OLD的内存大小;mx为最大可占用的YOUNG+OLD内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。
NewSize/MaxNewSize:定义YOUNG段的尺寸,NewSize为JVM启动时YOUNG的内存大小;MaxNewSize为最大可占用的YOUNG内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。
PermSize/MaxPermSize:定义Perm段的尺寸,PermSize为JVM启动时Perm的内存大小;MaxPermSize为最大可占用的Perm内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。
SurvivorRatio:设置Survivor空间和Eden空间的比例
内存溢出的可能性
1. OLD段溢出
这种内存溢出是最常见的情况之一,产生的原因可能是:
1) 设置的内存参数过小(ms/mx, NewSize/MaxNewSize)
2) 程序问题
单个程序持续进行消耗内存的处理,如循环几千次的字符串处理,对字符串处理应建议使用StringBuffer。此时不会报内存溢出错,却会使系统持续垃圾收集,无法处理其它请求,相关问题程序可通过ThreadDump获取(见系统问题诊断一章)单个程序所申请内存过大,有的程序会申请几十乃至几百兆内存,此时JVM也会因无法申请到资源而出现内存溢出,对此首先要找到相关功能,然后交予程序员修改,要找到相关程序,必须在Apache日志中寻找。
当Java对象使用完毕后,其所引用的对象却没有销毁,使得JVM认为他还是活跃的对象而不进行回收,这样累计占用了大量内存而无法释放。由于目前市面上还没有对系统影响小的内存分析工具,故此时只能和程序员一起定位。
2. Perm段溢出
通常由于Perm段装载了大量的Servlet类而导致溢出,目前的解决办法:
1) 将PermSize扩大,一般256M能够满足要求
2) 若别无选择,则只能将servlet的路径加到CLASSPATH中,但一般不建议这么处理
3. C Heap溢出
系统对C Heap没有限制,故C Heap发生问题时,Java进程所占内存会持续增长,直到占用所有可用系统内存
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]。
第一种为单线程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。
1. Heap设定与垃圾回收
Java 内存分为3个区,Young,Old和Permanent。Young保存刚实例化的对象。当该区被填满时,GC会将对象移到Old区。
通常把前两个区域叫做堆区(Heap),Permanent区则负责保存反射对象,Class的meta信息等.
堆区发生内存溢出的异常为:java.lang.OutOfMemoryError: Java heap space,
Permanent区发生内存溢出是为:OutOfMemoryError: PermGen space.
JVM的Heap分配可以使用-X参数设定,
初始Heap大小&
java heap最大值&
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。
每个线程的Stack
Stack的大小限制着线程的数量。如果Stack过大就好导致内存溢漏。-Xss参数决定Stack大小,例如-Xss1024K。如果Stack太小,也会导致Stack溢漏。
3,Permanent区
程序发布时候可能遇到的OutOfMemoryError: PermGen space,Class在被加载的时就会被放到PermGen space中,
它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对
PermGen space进行清理,所以如果你的应用中有很多CLASS的话,就很可能出现PermGen space错误,
这种错误常见在web服务器对JSP进行pre compile的时候。
通过 -XX:PermSize=64M -XX:MaxPermSize=128m调整.
4.硬件环境
硬件环境也影响GC的效率,例如机器的种类,内存,swap空间,和CPU的数量。
如果你的程序需要频繁创建很多transient对象,会导致JVM频繁GC。这种情况你可以增加机器的内存,来减少Swap空间的使用[2]。
转自:/link?url=lK0U3qmwLMDsUZe2rq65yzMKsbPADs72ovl78Hbg3dz-0n910QX5ZbSPLrTMWbG5efYaYG_v8zmY4n-lSpyL42jNQsCtIhZrlYVt6PVMP9S标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&国之画&&&& &&&&chrome插件
版权所有 京ICP备号-2
迷上了代码!

我要回帖

更多关于 major.minor版本52 的文章

 

随机推荐