JVM 小结

1、jvm虚拟机的种类及特点   

  Sun Classic:解释和编译不能协调使用;使用基于句柄的对象查找。
  Exact VM:解释和编译能协调使用;采用准确式内存管理;可以知道内存中某个位置的数据是什么类型,便于GC判断数据是否还可用。
抛弃了基于句柄的对象查找。
  Sun HotSpot VM:热点代码探测,通过执行计数器找出最具有编译价值的代码;解释器和编译器配合使用。

2、jvm内存区域划分  

  运行时数据区域分为两种:1、线程隔离的数据区;2、所有线程共享的数据区。
  线程隔离区:

    程序计数器、栈【虚拟机、本地方法 C/C++ DLL】

  线程共享区:堆【java对象、数组】、
        方法区【.class 的基础上jvm编译后的本地代码、常量池、对象的逻辑区域】(方法区也称【非堆】)

3、栈: 

  包括Java虚拟机栈和本地方法栈的区别:
  虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。程序员人为的分为“堆栈”中的“栈”。

4、java堆的分代划分

  新生代【eden、s0,s1】和 老年代
    1、新对象出生在eden
    2、垃圾回收时,将eden+s0里可以存活的放到s1区。交替使用两块儿survior区域(复制算法)

  老年代:需要回收的对象,直接干掉。
注:
 1、通过-Xmx设置堆的最大内存和-Xms设置初始内存)
  java -Xms10m -Xmx100m Hello

5、方法区:

  1、对于HotSpot虚拟机是使用永久代来实现方法区;
  2、常量池技术,为了方便快捷地创建某些对象(需要对象,就从池中取(如果池中没有则创建),因此在需要重复创建相等变量时节省了很多时间。

6、Java内存区域:异常

  堆:报错后dump出信息: -XX:+HeapDumpOnOutOfMemoryError

7、java的对象引用分类

  强引用、软引用、弱引用、虚引用,强度依次减弱,区别如下:
  1、如果一个对象有强引用GC不会回收;可以获取对象属性
  2、如果一个对象只有软引用,内存溢出前,GC回收;可以获取对象属性;用途:做缓存;
  3、如果一个对象只有弱引用,GC肯定回收(只被弱引用关联的对象);可以获取对象属性
  4、如果一个对象只有虚引用,GC肯定回收;不可以获取对象属性,唯一的目的,对象被引用时,发一个通知到队列里。

6、对象的可达性分析

判断对象的存活方式:
  1、引用计数算法:给对象添加一个引用计数器,每引用值就加1;引用失效值就减1;任何时刻计数器为0的对象就是不可能再被使用的
  2、可达性分析:“GC Roots”的对象作为起始点,从这些节点开始向下搜索,当一个对象到GC Roots没有任何引用链相连(即不可达)
时,则证明此对象是不可用的。
对象的生死:
  注:不可达的对象真正死亡,需要两次标记;finalize()方法是对象逃脱死亡命运的最后一次机会;

GC Roots对象:
  虚拟机栈(栈帧中的本地变量表)中引用的对象。
  方法区中类静态属性引用的对象。
  方法区中常量引用的对象。
  本地方法栈中JNI(Java Native Interface即一般说的Native方法)引用的对象。

7、垃圾回收算法:

  “标记-清除”(Mark-Sweep)算法:标记要清除的对象,统一清除;
  缺点:
    效率问题,标记和清除两个过程的效率都不高;
    空间问题,标记清除之后会产生大量不连续的内存碎片;

标记整理算法 = 标记+清除+整理:用于回收老年代;

复制算法:它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当一块的内存用完,就将还存活着的对象复制到另外一块上面,
然后再把已使用过的内存空间一次清理掉。
  优点:无内存碎片,只要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。
  缺点:实际可用内存缩小为了原来的一半。
  用于回收新生代(新生代对象多,需要回收也多)。
  注:HotSpot虚拟机默认Eden和Survivor的大小比例是8:1:1;浪费10%。

8、GC方式分三种:

  Minor GC:每次 Minor GC 会清理年轻代的内存(包括 Eden 和 Survivor 区域)。

  Major GC:清理老年代或者永久代。

  Full GC:清理整个堆空间—包括年轻代和老年代或者永久代。

9、内存分配策略

  (1)、对象优先在Eden分配
  大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够的空间进行分配时,虚拟机将发起一次Minor GC。

  (2)、大对象直接进入老年代
  所谓大对象就是指,需要大量连续内存空间的Java对象,最典型的大对象就是那种很长的字符串及数组

  (3)、长期存活的对象将进入老年代
  虚拟机给每个对象定义了一个对象年龄(Age)计数器。若对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,
将被移动到Survivor空间中,并将对象年龄设为1。对象在Survivor区中每熬过一次Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认为15岁)时,就会被晋升到老年代中。对象晋升老年代的年龄阈值,可以通过参数-XX:MaxTenuringThreshold来设置。

  (4)、动态对象年龄判定
  虚拟机并不总是要求对象的年龄必须达到MaxTenuringThreshold才能晋升老年代,如果在Survivor空间中相同年龄所有对象大小的总和大于
Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄。

  (5)、空间分配担保

  在发生Minor GC前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间。
  1).如果大于,那么Minor GC可以确保是安全的。
  2).如果小于,虚拟机会查看HandlePromotionFailure设置值是否允许担任失败。
    a.如果允许,那么会继续检查老年代最大可用连续空间是否大于历次晋升老年代对象的平均大小
      ①.如果大于,将尝试着进行一次Minor GC,尽管这次Minor GC是有风险的
      ②.如果小于,进行一次Full GC.
    b.如果不允许,也要改为进行一次Full GC.
参考网址:
深入理解JVM03--内存分配与回收策略 - oChangWen的博客 - 博客频道 - CSDN.NEThttp://blog.csdn.net/ochangwen/article/details/51418314

10、收集器:

  收集器是内存回收的具体实现;
  垃圾收集器:
  1.Serial收集器(适合新生代) + (SerialOld收集器是Serial的老年代收集器,采用“标记-整理”)
    特点:单线程、stop-the-world 、复制算法

  2.ParNew收集器其实是Serial的多线程版本。新生代收集器
    特点:多线程、stop-the-world

  3.CMS(concurrent mark sweep)收集器是一个以获取最短回收停顿时间为目标的老年代收集器。
    特点:并发收集、低停顿。
    可以兼容的新生代收集器:ParNew和Serial

  4.Parallel Scanvenge收集器是一个新生代收集器,采用复制算法。
    特点:收集新生代,复制算法,多线程,高吞吐、自适应

  5.G1(Garbage-First):未来替调CMS收集器

11、jvm分析工具:

  jps:Java Virtual Machine Process Status Tool 主要查看进程ID

  jstatd:Virtual Machine jstat Daemon 启动jvm监控服务

  注:在Linux虚拟机上启动后,即可在宿主端的网页上访问;

  jmap 观察运行中的jvm物理内存的占用情况。

  jhat:分析查看
  用jmap把进程内存使用情况dump到文件中,再用jhat分析查看。
  注:dump出来的文件可以用MAT、VisualVM等工具查看

  jinfo:

  jstack:运行java程序的java stack和native stack的信息。可以轻松得知当前线程的运行情况

  jstat:

  jconsole:可视化的jvm监控软件。可以监控本地或者远程进程。
  主要包括:概览、内存、线程、类、VM概要、MBean选项卡。

  jvisual vm:多合一故障处理工具,功能最强大的运行监视和故障处理程序。可以查看本地和远程的的状态。

  JMX(Java Management Extensions,即Java管理扩展)是一个为应用程序、设备、系统等植入管理功能的框架。
  注:远程的线程dump可以dump查看,堆的dump是需要从远程拉到本地来查看。

 

posted @ 2015-07-20 20:23  VNX  阅读(259)  评论(0编辑  收藏  举报