码迷,mamicode.com
首页 > 编程语言 > 详细

Java 虚拟机

时间:2017-07-03 22:25:53      阅读:282      评论:0      收藏:0      [点我收藏+]

标签:png   详细   9.png   strong   create   log   查看   约束   垃圾回收算法   

15

Java虚拟机是一个进程,因此符合操作系统进程的特征,且是多线程的。整个虚拟机脱离不开操作系统的约束。

java虚拟机运行时运行结构图:

技术分享

一个进程包含多个线程。有些数据在线程中是共享的。

java虚拟机将内存划分为不同的区域,有些是在java虚拟机启动的时候就存在了,有些事随着线程的生成和销毁而存在的。

 

OOM -OUT OF Memory

1、操作系统的OOM killer

2、java虚拟机中的OOM 

2中OOM原理差不多。

//vm参数:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/Users/root/Documents/javaDump/
import java.util.ArrayList;
import java.util.List;
public class myjava {
    static class OOMObject{
    }
    public static void main(String[] args) throws InterruptedException {
        List<OOMObject> list = new ArrayList<OOMObject>();
        while(true){
            list.add(new OOMObject());
        }
    }
}
运行结果:
java.lang.OutOfMemoryError: Java heap space
Dumping heap to /Users/root/Documents/javaDump/java_pid1014.hprof ...
Heap dump file created [27569234 bytes in 0.121 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space    
技术分享
当内存达到20M会被KILL掉。并且dump到指定目录。

 Java虚拟机垃圾回收

1、回收什么?什么可以回收。

 

技术分享

以前的方式,查看对象有没有引用。如果没有引用,回收。但是像上图如果5,和6都没有用了,但是他们相互引用。就无法回收。

现在使用左边的图。通过维护一个GC根。所有对象都能到达根,就说明不能回收。如果不能到达根,即使引用不是0,也能回收。就像上图。5,6,7的引用都不是0,但是无法到达根,java虚拟机也会回收。

上面的程序:

每个Arrylist都是存放OOMObject对象。

在while循环中,一直没有执行完。所有的对象一直指向根Arraylist。一直没有被释放掉,所以OOM

如果执行完,就可以被释放。

java虚拟机在OOM之前,进行过多次垃圾回收。只是没有回收完。

-XX:+PrintGC 加一个参数,打印GC信息

[GC (Allocation Failure)  4986K->3457K(19968K), 0.0057425 secs]

[GC (Allocation Failure)  8994K->8000K(19968K), 0.0102037 secs]

[Full GC (Ergonomics)  16797K->12588K(19968K), 0.1313456 secs]

[Full GC (Ergonomics)  16266K->16101K(19968K), 0.1299640 secs]

[Full GC (Allocation Failure)  16101K->16089K(19968K), 0.0809210 secs]

java.lang.OutOfMemoryError: Java heap space

Dumping heap to /Users/root/Documents/javaDump/java_pid1048.hprof ...

Heap dump file created [27569234 bytes in 0.173 secs]

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

2、什么时候回收

3、具体如何回收

通过jvisualvm查看java须立即内存堆的更详细的信息

//运行代码
public class mytest {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("********************************");
        Thread.sleep(1000*60*5);
        System.out.println("###############################");
    }
}

技术分享

技术分享

技术分享

元空间 = 方法区

old(老年代)+eden(年轻带)+s0+s1=堆空间。

每部分都有自己的垃圾回收算法

新生成的对象,一般都放在eden和s0。死亡率比较高

一般垃圾回收先在eden区回收,如果经过很多次回收都没有被回收掉,对象就会被移动到old区,有资格进入old区 一般都是长时间都在使用的对象

eden+s0使用频繁,也会频繁的进行回收。死亡率高。采用复制策略。就是把剩下的复制到s1或者复制到old

在老年代采用的回收策略,标记-整理或标记的 清理算法。有些类可以回收了,就先标记。可以死亡了,就进行回收。

指定jc。下图为jdk1.7版本的

技术分享

这个图,2中算法之间如果没有线连着,表示不能共存。比如年轻带指定parallel Scavenge 那么来年代只能使用serial old或者parallel old 。不能使用cms

 Stop the world

-XX:+PrintGCDetails  //打印GC详细信息
-XX:+PrintGC //打印GC一般信息

运行第一个程序,打印GC详细信息。运行结果如下:

[GC (Allocation Failure) [PSYoungGen(新生代): 4995K(回收前)->480K(回收后)(6144K)(总大小)] 4995K(回收前整体)->3433K(回收后整体)(19968K)整体堆空间 Xms和Xmx设置的大小, 0.0068095 secs(用时)] [Times: user=0.02(系统用户态使用时间) sys=0.00(系统态), real=0.01(真实感知的时间。比如有3个CPU,每个CPU都占了0.01,那user就是0.03,但是是同时并行的,所以用户感知可能只用了0.015) secs] 
[GC (Allocation Failure) [PSYoungGen: 6017K->496K(6144K)] 8970K->8000K(19968K), 0.0110276 secs] [Times: user=0.02 sys=0.01, real=0.01 secs] 
[Full GC (Ergonomics) [PSYoungGen: 6128K->0K(6144K)] [ParOldGen(老年代): 10669K->12588K(13824K)] 16797K->12588K(19968K), [Metaspace(元空间): 2620K->2620K(1056768K)], 0.1348238 secs] [Times: user=0.26 sys=0.00, real=0.14 secs] 
[Full GC (Ergonomics) [PSYoungGen: 3676K->2488K(6144K)] [ParOldGen: 12588K->13612K(13824K)] 16265K->16101K(19968K), [Metaspace: 2620K->2620K(1056768K)], 0.1376546 secs] [Times: user=0.39 sys=0.01, real=0.14 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 2488K->2488K(6144K)] [ParOldGen: 13612K->13600K(13824K)(老年代增大)] 16101K->16089K(19968K), [Metaspace: 2620K->2620K(1056768K)], 0.1072099 secs] [Times: user=0.26 sys=0.01, real=0.11 secs] 
java.lang.OutOfMemoryError: Java heap space
Dumping heap to /Users/root/Documents/javaDump/java_pid1444.hprof ...
Heap dump file created [27569234 bytes in 0.135 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3210)
    at java.util.Arrays.copyOf(Arrays.java:3181)
    at java.util.ArrayList.grow(ArrayList.java:261)
    at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)
    at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)
    at java.util.ArrayList.add(ArrayList.java:458)
    at myjava.main(myjava.java:11)
Heap
 PSYoungGen      total 6144K, used 2711K [0x00000007bf980000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 5632K, 48% used [0x00000007bf980000,0x00000007bfc25d80,0x00000007bff00000)
  from space 512K, 0% used [0x00000007bff80000,0x00000007bff80000,0x00000007c0000000)
  to   space 512K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007bff80000)
 ParOldGen       total 13824K, used 13600K [0x00000007bec00000, 0x00000007bf980000, 0x00000007bf980000)
  object space 13824K, 98% used [0x00000007bec00000,0x00000007bf9481b0,0x00000007bf980000)
 Metaspace       used 2652K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 289K, capacity 386K, committed 512K, reserved 1048576K

Jstat

import java.util.ArrayList;
import java.util.List;
public class myjava {
    static class OOMObject{
        
    }
    public static void main(String[] args) throws InterruptedException {
        List<OOMObject> list = new ArrayList<OOMObject>();
        Thread.sleep(15000);
        while(true){
            list.add(new OOMObject());
        }
    }
}

jstat -gc pid 1000(多久打印一次) 20(多少次)

jstat -gc pid 1000(多久打印一次) 20 > a.txt 保存到文件

 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
8192.0 8192.0  0.0    0.0   51712.0   2068.5   136704.0     0.0     4480.0 774.4  384.0   75.9       0    0.000   0      0.000    0.000
8192.0 8192.0  0.0    0.0   51712.0   2068.5   136704.0     0.0     4480.0 774.4  384.0   75.9       0    0.000   0      0.000    0.000
C最大大小 U使用  
YGC GC次数
YGCT 新生代在垃圾回收里一共占用了多少时间
GCT GC总共暂用多少时间 包括YGC FGC

jstat -gcutil pid 1000 20

jmap

可以用visualVM装入dump文件

 技术分享

技术分享

 

 

 

 

-XX:+PrintFlagsFinal 

 

Java 虚拟机

标签:png   详细   9.png   strong   create   log   查看   约束   垃圾回收算法   

原文地址:http://www.cnblogs.com/milanmi/p/7111374.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!