深入理解Java虚拟机读书笔记之内存管理

一、Java的内存主要有如下的部分组成:

 堆内存:存放对象或者数组实例。可以使用-Xms指定最小值,-Xmx指定最大值。分为新生带和老年点。其中新生代又可以分为伊甸园区和两个Survivor0区和Survivor1区,他们的内存比例用-XX:SurvivorRadio=X指定,例如如果这个值等于6,那么表示伊甸园区的内存总数为 新生代x6/(6+2)。内存溢出信息为:Java heap space。该内存区域为整个进程共享

方法区:存放加载类信息、静态常量以及即时编译器编译的本地代码。可以使用-XX:PermSize指定最小值,-XX:MaxPermSize指定最大值。内存溢出异常的信息为:PermGen space。该内存区域为整个进程共享

虚拟机栈:该区域为线程私有。主要存在本地变量表、最大操作数、动态连接、方法出口等信息。每个线程的虚拟机栈内存可以通过-Xss设定栈容量。

本地方法栈:在HotSpot虚拟机中和虚拟机栈合二为一。调用native方法。该区域为线程私有

程序计数器:记录当前线程执行字节码的行号。当进行多线程切换回来的时候可以找到正确的执行位置。

直接内存:在NIO中可以通过native方法直接分配内存。可以通过-XX:MaxDirectMemorySize指定,如果不指定。默认和java堆最大值一样。通过sun.misc.Unsafe的allocateMemory方法分配。

二、对象的访问方式:

    Sun Hotspot虚拟机使用直接指针的方式,对象的reference的值为堆内存中的内存地址。Java对象存储分为三部分 1.对象头:存储对象本身的状态和类型指针。2、实例数据:3、对齐填充(非必须)


深入理解Java虚拟机读书笔记之内存管理_第1张图片

三、垃圾回收

   1、什么样的对象会被回收掉

        使用 根搜索算法:只要能被root 链上引用到的就不会被回收。可以作为Root对象的有当前线程所在的变量(本地变量表)、类或者接口定义的静态变量。而不使用引用计数算法的原因是该算法不能解决循环引用的问题。

   2、在对象回收前如果用户复写了对象的finalize方法,在回收之前会调用这个方法,但是一个实例对象只会调用一次。建议不要使用该方法。

   3、java中对象的引用分为强引用(new Object()方式)、软引用(只有发生内存溢出的时候才会回收这些对象)、弱引用(下一次垃圾回收)、虚引用(拿不到引用的对象)

   4、垃圾收集的算法:A.标记-清除算法。这种算法内存碎片比较多,一般用于老年代。B复制算法:速度比较快,但是浪费了部分内存空间。一般用在新生代(新生代的分区)C标记-整理算法:速度比较慢,一般用于老年代。

    5、垃圾收集器。Serial收集器:垃圾收集的时候,暂停其他线程,使用单一的线程进行垃圾收集。ParNew收集器:垃圾收集的时候,暂停其他线程,使用多个的线程进行垃圾收集。其他收集器...

   6、内存分配和回收策略:

        A、对象优先在伊甸园区分配B、大对象可以直接进入老年代,可以通过-XX:PretenureSizeThreshold C、长期存活的对象进入老年代(每次Minor GC,对象年龄+1)。可以通过-XX:MaxTenuringThreshold指定对象的年龄。D、如果某个年龄的对象所占的内存大于新生代的一半,那么大于等于该年龄的对象会进入老年代。E、老年代的担保策略:如果老年代所剩的容量小于进入老年代对象的容量会进行Full GC。FullGC会比较耗时。  

四、工具篇

   1、VisualVm的BTrace插件,使用代码热交换技术。

 

 

你可能感兴趣的:(jvm)