自学内容网 自学内容网

内存图及其画法

所有的文件都存在硬盘上,首次使用的时候才会进入内存

进程:有自己的Main方法,并且依赖自己Main运行起来的程序。独占一块内存区域,互不干扰。内存中有一个一个的进程。

操作系统只认识c语言。操作系统调度驱动管理硬件,所以卖硬件的时候要配驱动,要不用户不会用,而驱动基本以c语言为主,操作系统直接调动驱动(以驱动为主),所以只认识c语言。

  • java等语言会转成c语言,操作系统在内存上运行他们。
  • 操作系统是内存管理的核心组件,它负责协调和优化内存的使用,以确保计算机系统高效、稳定地运行。

用数组以c语言申请空间。java把内存空间分成五大份如下:

方法区

只写了这两个常量池

Test.java:

package 内存图;

public class Test {
    
    public static void main(String[] mmm) {
        
        Person x1 = new Person();

        
    }
    public static void m1() {        
    }
    public static void m2() {
            
    }
    public static void m3() {
        
    }
    public static void m4() {
        
    }
    public static void m5() {
        
    }
    public void m6() {
        
    }
}

Person.java:

package 内存图;

public class Person{
    public int age;
    public String name;
    public static int flag;
    public void m1(){  //static--静态修饰

    }
    public void m2(){

    }
    public static void m3(){

    }
}

static有无的区别:

静态方法(有颜色的那部分)实际存储在静态常量池,类信息常量池只是指向它的指针

静态的方法可以调用静态的,非静态的可以调用静态的和非静态的。被static方法修饰的可以直接被调用。解释如下:

静态的相当于被创造出来了,可以直接调用。非静态的没有被造出来,不能直接调用,但是同级别的都在图纸上,非静态之间可以互相被调用。

栈,堆

方法被调用是拷贝一份入栈,方法执行完毕之后就会出栈。

package 内存图;

public class Test {
    
    public static void main(String[] mmm) {        
        
                Person x1 = new Person();

                //基本类型的值和句柄在一块
                int a = 9;
                //引用类型,无法预估大小,b是个变量,没办法在栈中申请空间,它的句柄(变量)与值没有在一块
        String b = "asd";
        m1();
        m2();
        int c = 20;
        if(a < c) {
            int k = 12;
            if(k > a)
   //作用域的内部原理:(超作用域就不能操作了)
   //在此范围内新声明变量的句柄要被消掉,找对应的括号,执行完之后在他里面声明的变量都要被摧毁
                        {
                String w = b;
            }
   
        }
    }
    public static void m1() {
        m3();
    }
    public static void m2() {
        m4();
    }
    public static void m3() {
        m5();
    }
    public static void m4() {
 //静态被创造出来了,不再创造了,所以要创造非静态的。调动方法的话也是调动创造出来的方法(白色的:非静态的),拷贝这个创造出来的方法入栈
 //静态的方法或属性在方法区的静态常量池里面只有一份,非静态的方法在每个对象里面都有一份
              Person xx = new Person(); // Person类型的,底层是指针 *xx = (*)maolloc(); 申请空间
        xx.m1();
  
                Person xx2 = new Person();
        xx2.m2();
                xx.m2();
  //静态的可以通过类或对象来调用(指针可以直接调用静态常量池里面的),非静态的只能通过对象来调用。
                Person.m3();                                                             
    }
    public static void m5() {
        
    }
    public void m6() {
        
    }
}
  • 基本类型的值和句柄在一块;
  • 引用类型,无法预估大小,b是个变量,没办法在栈中申请空间,它的句柄(变量)与值没有在一块,与 c语言的指针一模一样。

调用一个方法之后,该方法入栈之后要运行,此时其他方法都停止运行。只有最上面的方法才会运行,变成最上面了就会恢复运行。运行完毕会出去。一个方法下面的方法就是调动它的方法。

//静态被创造出来了,不再创造了,所以要创造非静态的。调动方法的话也是调动创造出来的方法(右边白色的:非静态的),拷贝这个创造出来的方法入栈

//静态的方法或属性在方法区的静态常量池里面只有一份,非静态的方法在每个对象里面都有一份。其他语言也是如此。

里面实际是这样的(指针的大小通常是4字节(在32位系统上)或8字节(在64位系统上))

下面的二进制每次都是读一部分

c语言中要自己写free()回收内存,java中有垃圾回收机制,没人指向的话就会自动回收。

  • 堆中常量池中生成的没人指向不会被销毁,除非常量池内存不够了;其他地方生成的没人指向会被回收。

进程的组成单位是线程(以上的所有过程),线程---依托栈结构完成了一条线的方法的调用,线程的组成单位是方法。

程序计数器:配合栈使用,记录方法的开始结束、变量的有效范围等

本地方法栈:操作系统本身,进行同步翻译(把自定义的c语言转换成操作系统所带的c语言)

任何程序的运行都需要硬件来实现,对硬件的操控需要驱动,操作系统内核来调度驱动(不能同时驱动)

java变成c语言(java自定义c),把自定义的c语言方法翻译成操作系统内的c(通过本地方法栈)

一个程序的地址的长度都是固定的(32bit / 64bit)

  • 指针赋值 (a = "123"):a是一个指向字符的指针。表达式a = "123"意味着将指针a指向一个字符串常量"123"的首地址。改变了指针a的地址,使其指向了新字符串的起始位置。a现在指向了"123"这个字符串。
  • 解引用赋值 *a = "123" 改变指针所指向地址的值,但不能将字符串常量直接赋值给*a。

值不变:

a,b的指向通过w互换了,x1,x2没有受到影响

方法出栈后,可看到x1,x2没有受到影响

对别人产生影响:改变它的指向;改变指向区域的值

值传递

传的是数字或值的地址 new Person();也是值(对象的地址)

传这边的地址:

不同方法中的对象可以指向同一个值

方法1中的对象调用其他方法,调用完成后该方法1中的值、指向没有改变

C语言,java等

引用传递

传x1,x2的地址(句柄的地址)

c++中&a传的是引用

Sring类型的数组和二维数组

String[] arr3 = {"aa","cc",new String("mmm"),"aaa"};

String类型(引用类型)不能在原地存,存的是它的地址

int[] arr1 = {1,2,3,4}; //引用类型 基本类型:byte short int long float double char boolean
arr1 = new  int[] {2,2,3,1,3}; //不管长短,不管占不占满,都新生成一个内存页,不能在原地改
int[] arr2 = arr1;
String[] arr3 = {"aa","cc",new String("mmm"),"aaa"};
arr3[0] = "aaa";
arr3[1] = "aaaa";
Person aa = new Person();
Person[] arr4  = {new Person(), new Person(),aa};

变量不赋值默认都是0

package neicun;
public class test{
    public static void main(String[] nnn){
        int[][] arr={
            {1,2},
            {2,2},
            {3},
            {1,1,4}
        };
        int[][] arr2 = new int[3][2];// 3个一维数组,每个数组里面有两个数字,里面默认都是0
        arr2[1]=new int[] {3,4,5,6};
        String[][] arr3 = {
            {"aa","vv"}, {"cc","ww","ff"}, {new String("xxx")}
        };
        int[][][] arr5 = {
            { {1},{2,2} },
            { {3,4},{1} }
        };


    }
}


原文地址:https://blog.csdn.net/qq_73993301/article/details/144301175

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!