Depth understanding of java virtual machine 2- notes

Disclaimer: This article is a blogger original article, welcome to reprint. https://blog.csdn.net/guo_xl/article/details/91358266

VM stack and native method stack overflow

General native method stacks rarely overflows, stack overflows more common virtual machine

  • Code 1
//VM args :-Xss128k  指定帧栈的容量
	public void hello() {
		hello();
	}

	public static void main(String[] args) {
		StackOverFlow stackOverFlow = new StackOverFlow();
		//线程栈里的VMstack是有限的,也就是容纳的栈帧数是有限的
		//栈帧数不断的增加会最后导致stack over flow,叫栈溢出
		stackOverFlow.hello();
	}

An error

Exception in thread "main" java.lang.StackOverflowError
	at rechard.learn.jvm.StackOverFlow.hello(StackOverFlow.java:8)
	at rechard.learn.jvm.StackOverFlow.hello(StackOverFlow.java:8)
  • Code 2
public static void main(String[]args){
		while(true){
			//jvm里的内存是有限的,
			//线程创建出来,线程栈是需要一定的内存的
			//一直创建线程,并且线程一直在运行,也就是GC不会回收这些线程,
			//迟早会出现内存溢出,出现oom
			//解决方法:
			//1.控制线程数,通过线程池控制。 Excutors.newxxxx
			//2.-xss:减小线程栈的内存分配以达到能创建更多的线程数
			new Thread(new Runnable(){
				public void run() {
					while(true){
						try {
							Thread.sleep(10);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
				
			}).start();
		}
	}

An error

Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
	at java.lang.Thread.start0(Native Method)
	at java.lang.Thread.start(Thread.java:717)
	at rechard.learn.jvm.StackoutOfMemory.main(StackoutOfMemory.java:25)

Lack of heap memory

//vm args:-Xmx20M -Xms20M -verbose:gc
//堆里不断的创建对象,最后会造成堆里的内存空间不足,而导致oom
	public static void main(String []args){
		List cases = new ArrayList();
	    while(true){	    	
	        cases.add(new Object());
	    }
	}

Given as follows

[GC (Allocation Failure)  5572K->2988K(19968K), 0.0081114 secs]
[GC (Allocation Failure)  8620K->7087K(19968K), 0.0150993 secs]
[GC (Allocation Failure)  12719K->12733K(19968K), 0.0168034 secs]
[Full GC (Ergonomics)  12733K->10732K(19968K), 0.2536876 secs]
[Full GC (Ergonomics)  16364K->14254K(19968K), 0.1547094 secs]
[Full GC (Ergonomics)  16696K->16599K(19968K), 0.2127199 secs]
[Full GC (Allocation Failure) Exception in thread "main"  16599K->16580K(19968K), 0.1892626 secs]
java.lang.OutOfMemoryError: Java heap space

Methods overflow

Runtime constant pool is part of the district method, the runtime constant pool has been placed at 1.8 in a heap

public static void main(String[] args) {  
        List<String> list = new ArrayList<String>();  
        int i = 0;  
        while(true){  
            list.add(String.valueOf(i++).intern());
            //System.out.println(i);
        }
    }  

An error

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.lang.Integer.toString(Integer.java:401)
	at java.lang.String.valueOf(String.java:3099)
	at rechard.learn.jvm.StringInternOOM.main(StringInternOOM.java:12)

Plus -verbose:gc -Xmx20Mafter

[Full GC (Ergonomics)  19455K->19455K(19968K), 0.1024099 secs]
[Full GC (Allocation Failure)  19455K->19455K(19968K), 0.1182977 secs]
[Full GC (Ergonomics) Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

Visible heap finally 19455K-> 19455K (19968K), shows that the constant pool in the heap

The strange thing is let go of the above code System.out.println(i);, an error has become

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
	at java.lang.Integer.toString(Integer.java:401)
	at java.lang.String.valueOf(String.java:3099)
	at java.io.PrintStream.print(PrintStream.java:597)
	at java.io.PrintStream.println(PrintStream.java:736)
	at rechard.learn.jvm.StringInternOOM.main(StringInternOOM.java:13)

More than 98% of the time used for GC and recovers throws this exception when less than 2% of heap memory. You can use
-XX: -UseGCOverheadLimit disable this check will become
[Full GC (Ergonomics) Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

String.intern

When the intern method is invoked, if the pool already contains a
* string equal to this {@code String} object as determined by
* the {@link #equals(Object)} method, then the string from the pool is
* returned. Otherwise, this {@code String} object is added to the
* pool and a reference to this {@code String} object is returned.

The official explanation: If the constant pool already contains the string object, then the object is returned directly, if not, add this object to the constant pool and then return

 public static void main(String[] args) {
        String b=new String ("A").intern();//创建后返回
        String a="A";
        String c=new String("A");
        System.out.println(a==b); 
        System.out.println(a==c);

        String d=new String ("B");
        String d1=d.intern();
        System.out.println(d==d1);

        System.out.println(d1=="B");
    }

operation result

true
false
false
true

By javap -v StringDemo.class analysis

constant pool:
   #1 = Methodref          #10.#34        // java/lang/Object."<init>":()V
   #2 = Class              #35            // java/lang/String
   #3 = String             #36            // A
  。。。

Code:
      stack=3, locals=6, args_size=1
         0: new           #2                  // class java/lang/String  new 一个引用类型并压入栈顶
         3: dup   //对栈顶复制一份并压入栈顶
         4: ldc           #3                  // String A 将int ,float或String  类型从本地变量表里的压栈,这里是#3,即对应constant pool里的#3,即将A 入栈
         6: invokespecial #4                  // Method java/lang/String."<init>":(Ljava/lang/String;)V // 调用<init>
         9: invokevirtual #5                  // Method java/lang/String.intern:()Ljava/lang/String;  //调用intern
        12: astore_1                            //  9里执行完其实是将常量池里的"A"的引用压栈,astore_1  是将栈顶的引用存入到第2个本地变量中,本地变量表是虚拟机栈的一部分,对应上面的locals=6是说本地变量表 有6个,对应下面的 LocalVariableTable 里的13     100     1     b   Ljava/lang/String; 即将"A" 付给了b
        13: ldc           #3                  // String A  //同上面4的注释
        15: astore_2      // 对应下面的LocalVariableTable里的第3行,即将"A"付给了a
        。。。
     LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0     113     0  args   [Ljava/lang/String;
           13     100     1     b   Ljava/lang/String;
           16      97     2     a   Ljava/lang/String;


Guess you like

Origin blog.csdn.net/guo_xl/article/details/91358266