深入浅出了解JVM

JVM的基本结构

了解JVM是每个学java人的必经之路,JVM对于java就像心脏对于人一样,JVM的结构如下图:
JVM的基本结构
1. PC寄存器
每个线程拥有一个PC寄存器,在线程创建时创建,指向的是下一条指令地址,但是在执行本地方法时,PC的值是未定义的。
2. 方法区
保存装载的类的元信息(类型的常量池,字段、方法信息,方法字节码等),被所以的线程共享
3. java堆
和方法区一样,所以的线程都共享java 堆,对分代GC算法来说,堆也是分代的,结构如下:
java堆
4. java栈
java栈为线程私有,由一系列帧组成,帧中保存一个方法的局部变量、操作数栈、常量池指针
注意:小对象在没有逃逸的情况下,可以直接分配在栈上,如果要取消优化可以使用-XX:-DoEscapeAnalysis参数
5. java线程
每一个线程有一个私有工作内存(java栈、本地栈、PC寄存器),这个工作内存与主内存是独立的,并且工作内存存放主存中变量值的拷贝,工作内存和主存之间可以用下图表示:
thread内存模型
当数据从主存复制到工作内存时,必须经过两个动作:read由主存执行读操作,load由工作内存执行load操作;当数据从工作内存拷贝到主存时,也必须经过两个动作:store由工作内存执行store操作,write主存相应的write操作。
因此对于普通变量,一个线程更新的值,不能马上反应在主存中,可以使用volatile关键字来消除这种情况,但是volatile并不能保证100%的同步,因为指令重排会破坏线程间的有序性,如下面这个例子:

class Test
{
    volatile int a=0;
    boolean flag=false;
    //线程1调用
    public void writer()
    {
        a=1;
        flag=true;
        /*上面两条语句在编译时为了优化,可能发生指令重排,重排后的结果如下
        *flag=true;
        *a=1;
        */
    }
    //线程2调用
    public void reader()
    {
        if(flag)
        {
            int i=a+1;
            ......
        }
    }
}

JVM的配置参数

  1. -verbose:[gc|class|jni]
    打开GC日志,显示已加载类的信息,显示有关JNI调用的信息
  2. -XX:+PrintGC、-XX:+PrintGCDetails、-XX:+PrintGCTimeStamps
    显示GC的信息
  3. -Xloggc:path
    指定GC log的位置,以文件输出
  4. -XX:PrintHeapAtGC
    每次GC后,都打印堆信息
  5. -XX:+TraceClassLoading
    监控类的加载,与-verbose:class相同
  6. -XX:+PrintClassHistogram
    打印类的信息
  7. -Xmx -Xms
    指定最大堆和最小堆
  8. -Xmn -XX:NewRatio -XX:SurvivorRatio
    设置新生代的大小、新生代与老年代的比值、老年代与幸存器的比值
  9. -XX:+HeapDumpOnOutOfMemoryError -XX:+HeapDumpPath -XX:OnOutOfMemoryError
    OOM时导出堆到文件及文件的路径、执行的脚本
  10. -Xss
    分配栈的大小

类装载器

class装载流程

  1. 加载
    装载类的第一个阶段,取得类的二进制流,转为方法区数据结构,在java堆中生成对应的java.lang.Class对象
  2. 链接
    1. 验证
      验证的目的是保证Class流的格式是正确的,包括文件格式验证(是否以0xCAFEBABE开头、版本号是否合理),元数据验证(是否有父类、是否继承了final类等),字节码验证,符号引用验证
    2. 准备
      分配内存,并为类设置初始值(方法区中)
      注意 final static变量在这阶段被直接赋值
    3. 解析
      将符号引用替换为直接引用
  3. 初始化
    1. 执行类的构造器clinit(包括static变量赋值语句、static 语句块)
    2. 子类的clinit调用前保证父类的clinit被调用
    3. clinit是线程安全的

JDK中的ClassLoader

classLoader

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值