java基础

JAVA内存管理

2016-11-21  本文已影响56人  听歌的老头

JAVA内存管理

JVM结构

JVM内存模型(Runtime data area)

Runtime data area 主要包括五个部分:Heap (堆), Method Area(方法区域),
Java Stack(java 的栈), Program Counter(程序计数器), Native method
stack(本地方法栈)。Heap 和Method Area 是被所有线程的共享使用的;而Java
stack, Program counter 和Native method stack 是以线程为粒度的,每个线
程独自拥。(这里可能出现的异常java.lang.OutOfMemoryError:
Java heap space)

public class TestStackOverFlow {
    //Exception in thread "main" java.lang.StackOverflowError  
    public static void main(String[] args) {
        System.out.println("start------------");
        Recursion recursion = new Recursion();
        recursion.doAction(100000);
        System.out.println("end-----------");
    }

    static class Recursion {
        public int doAction(int n) {
            if (n <= 1) {
                return 1;
            }
            return n + doAction(n - 1);
        }
    }
} 

Sun JVM的内存管理

JVM Specification 只是抽象的说明了JVM 实例按照子系统、内存区、数据类型
以及指令这几个术语来描述的,但是规范并非是要强制规定Java 虚拟机实现内
部的体系结构,更多的是为了严格地定义这些实现的外部特征。
Sun JVM 实现中:Runtime data area(JVM 内存) 五个部分中的Java Stack ,
Program Counter, Native method stack 三部分和规范中的描述基本一致;但
对Heap 和Method Area 进行了自己独特的实现,这与Sun JVM的内存管理和Garbage
collector(垃圾回收)机制有关,下面我们来重点介绍。

JVM的分代


备注:

疑问:Permanent Space属于堆还是Method Area?
Method Area 在HotSpot JVM的实现中属于非堆区,非堆区包括两部分:Permanet Generation和Code Cache,而Method Area属于Permanert Generation的一部分。Permanent Generation用来存储类信息,比如说:class definitions,structures,methods, field, method (data and code) 和 constants。Code Cache用来存储Compiled Code,即编译好的本地代码,在HotSpot JVM中通过JIT(Just In Time) Compiler生成,JIT是即时编译器,他是为了提高指令的执行效率,把字节码文件编译成本地机器代码。对于不同厂家和不同版本的JDK实现有差别,最靠谱的方法还是JVM Specification

更详细的介绍可以参考:http://www.cnblogs.com/duanxz/p/3724120.html

JVM Heap:从广义的角度来说,JVM堆内存在物理上被划分为两个部分Young Generation(年轻代)和Old Generation(老年代)。

JVM参数说明
(如果你发现上述参数不满足你需求,请读这里,JVM Options Official Page.)
查看命令:jmap–heap [pid]
-Xms:JVM启动时设置初始堆大小,默认是物理内存的1/64;
-Xmx:最大堆大小,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制。一般设置xmx和xms一样,避免每次GC调整堆大小 -Xmn:年轻代大小,剩下的空间分配给老年代
-XX:PermGen:初始永久代大小
-XX:MaxPermGen:最大永久代大小
-XX:SurvivorRatio:Eden区和Survivor区的比率,例如,如果年轻代总共大小为10M,这个参数设置为-XX:SurvivorRatio=2 那么Eden区域获得5M,SO,S1分别是2.5M,默认值为8
-XX:NewRatio:老年代和年轻代的比率,默认值为2
-XX:MaxTenuringThreshold: 用于控制对象在新生代存活的最大次数。默认值15
-XX:PretenureSizeThreshold=x,控制超过多大字节的对象就在old上分配

Garbage Collector

不同厂商的不同版本GC实现会略微不同。下面我们介绍Sun JDK 1.6 HotSpot的版本实现。下面demo代码中会涉及到GC日志,其解读可以参考Understanding Garbage Collection Logs

Serial Copying(串行GC)

单线程收集器,使用单线程完成所有GC工作,没有线程通信,较为高效。使用单处理器机器。JVM client模式下默认GC方式。可通过参数-XX:+UseSerialGC强行指定。

GC触发条件

Minor GC

Full GC:

GC触发时的工作

Minor GC:

Full GC:

ParNew(并行GC)
Parallel (并行回收GC)

Server模式下默认;YGC: PSYoungGen(Parallel Scavenge) FGC: Parallel MSC。可以通过-XX:+UseParallelGC或-XX:+UseParallelOldGC来强制指定;
– ParallelGC代表FGC为Parallel MSC
– ParallelOldGC代表FGC为Parallel Compacting

GC触发条件

Minor GC

Full GC:

GC触发时的工作

Minor GC:

Full GC:

Concurrent Mark-Sweep (CMS) Collector

GC触发条件

Minor GC

CMS GC

Full GC:

GC触发时的工作

Minor GC:

CMS GC

Full GC: 和Serial动作完全相同。

更多关于GC和GC的算法可以阅读神级文档jvm hotspot内存管理白皮书

参考文献

命令工具

上一篇 下一篇

猜你喜欢

热点阅读