JVM的内存管理

今天通过无意中看到了String类的intern()方法,意义是把这个String放入到运行时常量池。回顾了一下 深入java虚拟机 这本书,总结一下jvm的内存管理

方法区(Permanent Generation) VM Args:-XX:PermSize=10M -XX:MaxPermSize=10M。运行时常量池,类和方法的字节码文件的存储都在这个区。 这个区有些文章说没有GC,但是实际上现代的JVM也会对这个区进行GC,只是频率很低。 Spring会利用代理技术来支持AOP,产生的代理对象也在这个区。

VM栈(stack) VM Args:-Xss 线程运行的栈区,包括方法执行的帧(frame)和临时变量。32位系统如果不设置的话,默认是10M(待确认)

堆(Heap) VM Args:-Xms20m -Xmx20m 存放对象实例,为所有线程共享

关于堆又被划分为新生代(young generation)和旧生代(old generation)。 新生代又被隔离为(eden, survivor A, survivor B),这么划分的目的主要是为了防止内存碎片,通过复制收集算法来回收内存。 因为程序执行过程中会产生很多临时对象,而其中的大部分一次用完就基本没用了。所以如果eden区在不能满足要分配对象的空间的时候,就会触发一次minor GC。 minor GC扫描eden区,把继续存活的对象拷贝到Survivor A中。如果survivor区域的空间不够大,则直接拷贝到旧生代中
VM参数:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8通过分配byte[]来测试触发minor GC。 另外在eden经过GC后存活,并且survivor能容纳的对象,将移动到survivor空间内,如果对象在survivor中继续熬过若干次回收(默认为15次)将会被移动到旧生代中。在Minor GC触发时,会检测之前每次晋升到老年代的平均大小是否大于老年代的剩余空间,如果大于,改为直接进行一次Full GC,如果小于则查看HandlePromotionFailure设置看看是否允许担保失败,如果允许,那仍然进行Minor GC,如果不允许,则也要改为进行一次Full GC。

你可能感兴趣的:(内存管理)