• jvm内存初步了解


    最近学习一下多线程,所以了解一下线程不安全原因以及底层实现:

    jvm组成

    class Content :是由类加载器把class文件加载到内存中的一块内存,与class文件的区别只是存放的地址不同,内容完全一样,class文件放在硬盘上,classContent在内存中。

    class对象:是由类加载器对classContent解析出的对象,存放在方法区中。

    方法区(一种规范,以下两种实现不能共存):

      永久代:在堆上,jdk1.8之前用

      元空间:在直接内存里,最小20M,最大无穷,元空间最小最大一般设置成一样的,防止内存抖动,设置成物理内存的1/32

    虚拟机栈:默认1M,每创建一个线程,就会创建一个虚拟机栈。

      栈帧:在一个线程中每调用一个方法就会创建一个栈帧。

      栈帧的组成:

     

    局部变量表的大小在编译期就确定了

    java跨平台:jvm是基于内存的,java文件由javac编译成.class文件到硬盘上。

    分析下面一段代码:

     结构:

    运行的时候这就是一个线程,因此创建了一个虚拟机栈。

    变量j的内容,也就是new出来的东西在堆内存中,而指向这个变量的指针,也就是j 存放在方法区中,方法区中存放的是一个内存地址,与堆内存中这个变量的内存地址一致。

    4个方法:init,clinit,main,add。

    动态链接存的是类方法的直接地址,上边这个类编译解析后的方法区中有4个方法(init,main,add,clinit)

    在main方法中,j2是局部变量,j2指向的是堆内存中的对象。

    在add方法中,局部变量有两个但却占用3个slot,原因是在0的位置是this指针,所有非静态方法的局部变量0的位置都是 this指针

    a怎样实现赋值的?

    首先,局部变量表在index=1的位置创建a,操作数栈把10压入栈顶,然后操作数栈pop栈顶元素复制给a,b同理,

    怎么实现return a+b?

    把index=1的值压入操作数栈顶,把index=2的值压入操作数栈顶,然后pop  20,pop 10进行相加,相加后的值再压入栈。

    最后实现return(返回地址):

    4部分:把局部变量表的指针恢复到main方法的局部变量表指针,把操作数栈的指针恢复到main方法的操作数指针,把程序计数器指向到main方法内的位置,

    清空栈帧的内存。

    main方法的执行流程:

    操作数栈中创建压入一个空对象,然后复制这个空对象并压入,然后pop出这个对象复制给init方法局部变量index为0的this,然后继续pop出对象复制给main方法局部变量index为1的j2,此时操作数栈为空。。。

    下图的前4步就是new一个对象的过程。

    下图main方法还执行了一个打印操作,跟上图代码稍有区别。

    这里查看字节码用的是java Bytecode Editor,下载后运行jbe.sh,打开class文件。

    eclipse找class文件位置方法:

    window-show view -navigator,然后在bin目录下就是class文件,右键properties打开class文件的位置。

    推荐博客:https://blog.csdn.net/sureSand/article/details/78701477

    https://blog.csdn.net/wqq3670/article/details/105401190

    我不是程序员,我只是程序的搬运工
  • 相关阅读:
    简单工厂模式
    单例
    开发帮助网址
    图片上传
    数据提交
    存储过程
    标量值函数
    linux查看TCP各连接状态
    nginx配置文件nginx.conf
    php配置文件php-fpm.conf
  • 原文地址:https://www.cnblogs.com/keith0/p/12837981.html
Copyright © 2020-2023  润新知