关于java:java虚拟机虚拟机的前世今生

49次阅读

共计 2389 个字符,预计需要花费 6 分钟才能阅读完成。

每个线程应用,线程在运行时,在执行每个办法的时候回打包成一个栈帧,存储了局部变量表,操作数栈,动静链接,办法进口等信息,而后放入栈。每个时刻正在执行的以后办法就是虚拟机栈顶额栈帧。办法的执行就对应着栈帧在虚拟机栈中入栈和出栈的过程。

栈帧大小缺省为 1M,可用参数 -Xss 调整大小,例如:-Xss256k

简直所有的对象对调配在这,也就是垃圾回收产生的次要区域,可用以下参数调整:

-Xms: 堆的最小值
-Xmx: 堆的最大值
-Xmn: 新生代的大小
-xx:NewSize: 新生代最小值
-xx:MaxSize: 新生代最大值
如:-Xmx256m

办法去 / 永恒代

用于存储曾经被虚拟机加载的类信息,常量(“zdy”,“123”等),动态变量等数据;能够用以下参数调整:

jdk1.7 及以前:-XX:PermSize;-XX:MaxPermSize;
jdk1.8 当前:-XX:MetaspaceSize; -XX:MaxMetaspaceSize
jdk1.8 当前大小就只受本机总内存的限度
如:-XX:MaxMetaspaceSize=3M

间接内存

不是虚拟机运行时数据区的一部分,也不是 java 虚拟机标准中定义的内存区域;如果应用 NIO,这块区域会被频繁应用,在 java 堆内能够应用 directByteBuffer 对象间接援用并操作;
这块内存不受 java 堆大小限度,但受本机总内存的限度,能够通过 -XX:MaxDirectMemorySize 来设置(默认与堆内存最大值一样),所以也会呈现 oom(内存溢出)异样

各个版本内存区域的变动

  • jdk1.6: 运行时常量池在办法区中
  • jdk1.7:运行时常量池在堆中
  • jdk1.8:运行时常量池在堆中,办法区变成元空间
  • 站在线程角度来看

深刻辨析堆和栈

性能

  • 一栈帧的但凡存储办法调用的过程,并存储办法调用的过程中根本数据类型的变量(int,short,long,byte,float,double,boolean,char 等)以及对象的援用变量,其内存调配在栈上,变量出了作用域就会主动开释;
  • 而堆内存是用来存储 java 中的对象。无论是变量,还是类变量,他们指向的对象都是存储在堆内存中;

线程独享还是共享

  • 栈内存归属于单线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即栈内存能够了解成线程的公有内存。
  • 堆内存中的对象对所有线程可见。堆内存中的对象能够被所有线程拜访

闲暇大小

  • 栈内存要远远小于堆内存
栈上调配
  • 虚拟机提供的一种优化技术,根本思维是:对于线程公有的对象,将它打撒调配在栈上,而不是调配在堆上。益处是对象跟着办法调用自行销毁,不进行垃圾回收,进步新能
  • 栈上调配须要的技术根底,逃逸剖析。逃逸剖析的目标判断对象的作用域是否会逃逸出办法体。$\color{red}{留神,任何能够在多线程之间共享对象,肯定都属于逃逸对象}$。

代码如下

package com.enjoy.cap1;

public class StackAlloc {
    
    public static class User{public int id = 0;}
    
    public static void alloc() {User user = new  User();
        user.id = 5;
    }

    public static void main(String[] args) {long start = System.currentTimeMillis();
        for (int i = 0; i < 100000000; i++) {alloc();
        }
        long end = System.currentTimeMillis();
        System.out.println((end-start)+"ms");
    }

}

编译变量环境设置

-server -Xmx10m -Xms10m -XX:+PrintGC -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:-UseTLAB

运行后果:

[GC (Allocation Failure)  2047K->680K(9728K), 0.0007156 secs]
4ms

不是用逃逸剖析:

-server -Xmx10m -Xms10m -XX:+PrintGC -XX:-DoEscapeAnalysis -XX:+EliminateAllocations -XX:-UseTLAB

[GC (Allocation Failure)  2840K->792K(9728K), 0.0002678 secs]
[GC (Allocation Failure)  2840K->792K(9728K), 0.0002149 secs]
[GC (Allocation Failure)  2840K->792K(9728K), 0.0003496 secs]
1231ms

从试验找那个两个工夫来看,应用逃逸剖析比没有应用逃逸剖析要快 1227ms

  • 如何启用线上调配

-server : jvm 运行的模式之一,server 模式能力进行逃逸剖析,jvm 运行模式还有 mix/client
-Xmx10m 和 -Xms10m:堆的大小
-XX:+DoEscapeAnalysis:启动逃逸剖析(默认为关上)
-XX:+EliminateAllocations:标量替换(默认为关上)
-XX:-UseTLAB 敞开本地线程调配缓冲
TLAB:ThreadLocalAllocBuffe,具体解释参见下文《虚拟机中的对象 — 对象的调配 —-2)》

  • 对栈上调配产生影响的参数就是三个。-server,-XX:DoEscapeAnalysis 和 -XX:+EliminateAllocations, 任何一个发生变化都不会产生栈上调配,因为启动逃逸剖析和标量替换默认是关上,所有,在咱们例子中,JVM 的电参数只用 -server 一样能够有栈上替换的成果
元数据空间

受本机内存的影响

间接内存

受本机内存的影响

本文由博客一文多发平台 OpenWrite 公布!

正文完
 0