JVM内存
JVM内存可以简单分为
-
1.堆/栈。
-
2.新生代/老年代/永久代
-
3.堆/非堆
分类一
- 堆heap
主要存放对象的地方,比如new关键字、数组引用的对象…
- 栈stack
主要用于存放局部变量的地方
分类二
- 新生代
伊甸园:主要是刚刚创建的对象,还没有执行GC的时候的对象的存储空间。
存活区:主要存放GC之后,没有被回收的对象的存储空间
- 老年代
老年代:主要是存放多次GC任然未被回收的对象。
- 永久代
永久代:存放永远不会被回收的对象。比如class,常量池…
分类三
1.heap区又分为:
- Eden Space(伊甸园)
- Survivor Space(存活区)
- Old Gen(老年代)
2.非heap区又分:
- Code Cache(代码缓存区,JIT即时编译)
- Perm Gen(永久代)
- Jvm Stack(虚拟机栈)
- Local Method Statck(本地方法栈)
垃圾回收
JVM区域总体分两类,heap区和非heap区。
heap区又分为:
- Eden Space(伊甸园)、
- Survivor Space(幸存者区)、
- Old Gen(老年代)。
非heap区又分:
- Code Cache(代码缓存区);
- Perm Gen(永久代);
- Jvm Stack(java虚拟机栈);
- Local Method Statck(本地方法栈);
详细说明
-
Eden Space 伊甸园
1)对象被创建的时候首先放到这个区域,不能被垃圾回收的对象放入到to survivor区域。
-
Survivor Space存活区
1)在eden space内存区域中经过垃圾回收后没有被回收的对象。Survivor有两块区域,To Survivor、 From Survivor,这个两个区域的空间大小是一样的。
2)执行垃圾回收的时候Eden区域不能被回收的对象放入To Survivor,同时Eden区域的内存会在垃圾回收的过程中全部释放,From Survivor里不能被回收的对象也会被放入到To Survivor,然后To Survivor 和 From Survivor的标记会互换,始终保证to survivor是空的。
Eden Space和Survivor Space都属于新生代,新生代中执行的垃圾回收被称之为Minor GC,每一次GC后留下来的对象age加1。
-
Old Gen老年代
1)用于存放新生代中经过多次垃圾回收仍然存活的对象,也有可能是新生代分配不了内存的大对象会直接进入老年代。经过多次垃圾回收都没有被回收的对象,就会放入到老年代。
2)当老年代被放满后,虚拟机会进行垃圾回收,称之为Major GC。由于Major GC需对整个堆进行扫描和回收,又称为Full GC。
整个堆大小=年轻代大小 + 老年代大小。堆内存默认为物理内存的1/64;
-
Code Cache代码缓存区
1)它主要用于存放JIT所编译的代码。Code Cache代码缓冲区的大小在client模式下默认最大是32m,在server模式下默认是48m。
2)Code Cache缓存区是可能被充满的,当CodeCache满时,后台会收到CodeCache is full的警告信息
java.lang.OutOfMemoryError:new Out of swap space
-
Perm Gen永久代
存放Class和Meta的信息,Class被加载的时候放入这个区域。
如果加载很多Class或者有很多常量,改区域是有可能被充满的,后期版本据说常量池被放入到堆中。
默认大小为物理内存的1/64。
虚拟机调优参数
-
性能调优
// -XX:PermSize //设置用于Java堆的大页面尺寸 -XX:LargePageSizeInBytes=4m //GC后java堆中空闲量占的最大比例 -XX:MaxHeapFreeRatio=70 //新生代成对象能占用内存的最大值 -XX:MaxNewSize=size //老年代对象能占用内存的最大值 -XX:MaxPermSize=64m //GC后java堆中空闲量占的最小比例,默认空余堆内存小于40%时,JVM就扩大堆,直到-Xmx的最大限制 -XX:MinHeapFreeRatio=40 //GC后java堆中空闲量占的最小比例,默认空余堆内存大于70%时,JVM会减少堆,直到-Xms的最小限制 -XX:MaxHeapFreeRatio= //新生代内存容量与老生代内存容量的比例 -XX:NewRatio=2 //新生代对象生成时占用内存的默认值 -XX:NewSize=2.125m //Code Cache代码缓冲区 -XX:ReservedCodeCacheSize=32m // -XX:InitialCodeCacheSize= //设置线程栈大小,若为0则使用系统默认值 -XX:ThreadStackSize=512 //使用大页面内存 -XX:+UseLargePages
-
行为参数
//禁止调用System.gc();但jvm的gc仍然有效 -XX:-DisableExplicitGC //最大化文件描述符的数量限制 -XX:+MaxFDLimit //新生代GC优先于Full GC执行 -XX:+ScavengeBeforeFullGC //在抛出OOM之前限制jvm耗费在GC上的时间比例 -XX:+UseGCOverheadLimit //对老生代采用并发标记交换算法进行GC -XX:-UseConcMarkSweepGC //启用并行GC -XX:-UseParallelGC //对Full GC启用并行,当-XX:-UseParallelGC启用时该项自动启用 -XX:-UseParallelOldGC //启用串行GC -XX:-UseSerialGC //启用本地线程优先级 -XX:+UseThreadPriorities
-
调试参数
//打印消耗在JIT编译的时间 -XX:-CITime //保存错误日志或者数据到文件中 -XX:ErrorFile=./hs_err_pid<pid>.log //开启solaris特有的dtrace探针 -XX:-ExtendedDTraceProbes //指定导出堆信息时的路径或文件名 -XX:HeapDumpPath=./java_pid<pid>.hprof //当首次遭遇OOM时导出此时堆中相关信息 -XX:-HeapDumpOnOutOfMemoryError //出现致命ERROR之后运行自定义命令 -XX:OnError="<cmd args>;<cmd args>" //当首次遭遇OOM时执行自定义命令 -XX:OnOutOfMemoryError="<cmd args>;<cmd args>" //遇到Ctrl-Break后打印类实例的柱状信息,与jmap -histo功能相同 -XX:-PrintClassHistogram //遇到Ctrl-Break后打印并发锁的相关信息,与jstack -l功能相同 -XX:-PrintConcurrentLocks //打印在命令行中出现过的标记 -XX:-PrintCommandLineFlags //当一个方法被编译时打印相关信息 -XX:-PrintCompilation //每次GC时打印相关信息 -XX:-PrintGC //每次GC时打印详细信息 -XX:-PrintGC Details //打印每次GC的时间戳 -XX:-PrintGCTimeStamps //跟踪类的加载信息 -XX:-TraceClassLoading //跟踪被引用到的所有类的加载信息 -XX:-TraceClassLoadingPreorder //跟踪常量池 -XX:-TraceClassResolution //跟踪类的卸载信息 -XX:-TraceClassUnloading //跟踪类加载器约束的相关信息 -XX:-TraceLoaderConstraints