Java的内存分析以及数组的一些排序和方法

一 ,Java的内存分配

每种软件在运行时都会占用一片内存区域,Java也不例外,Java虚拟机会占用一片空间。

为了更好地利用这片空间,jvm把这片空间分为5大部分,每个部分都有自己独立的各自的作用。

在jvm中有独立的五个部分分别为:本地方法栈,寄存器,栈,堆,元空间

1.1本地方法栈

存储JNI方法的调用信息。

存储本地方法中的局部变量,操作栈等信息。

在执行本地方法时,本地方法栈会为本地代码分配内存并记录调用信息。与 Java 方法栈不同,本地方法栈执行的不是 JVM 字节码,而是本地机器代码

1.2寄存器

通常是指用于存储执行 Java 字节码指令时临时数据的硬件级存储单元。

1.3JVM 栈(Java Virtual Machine Stack)

是用于存储方法的局部变量、操作数栈、方法调用的执行状态等数据的内存区域。JVM 栈是每个线程私有的,也就是说,每个线程在 JVM 中都有一个独立的栈,它由多个 栈帧(Stack Frame)组成。每当一个方法被调用时,JVM 会为该方法创建一个新的栈帧,并将其压入栈中;当方法执行完毕时,栈帧会被1.3JVM 栈(Java Virtual Machine Stack)

是用于存储方法的局部变量、操作数栈、方法调用的执行状态等数据的内存区域。JVM 栈是每个线程私有的,也就是说,每个线程在 JVM 中都有一个独立的栈,它由多个 栈帧(Stack Frame)组成。每当一个方法被调用时,JVM 会为该方法创建一个新的栈帧,并将其压入栈中;当方法执行完毕时,栈帧会被弹出(弹栈)

变量都存在栈中(基本数据类型的直接存数据,引用数据类型的存引用地址,数据在引用地址对应的中存放)

1.4**JVM 堆(Heap)

只要是new出来的 都存在堆中!!!

是 JVM 中用于存储对象和数组的内存区域。堆是所有线程共享的内存区域,Java 中的对象和数组通常都分配在堆中,而局部变量和方法调用等数据则存储在 JVM 栈 中。堆是 Java 内存管理的关键部分,负责为对象的实例分配内存并通过 垃圾回收(GC)来管理内存的释放。

总结: 只要是new 出来的都要存放到堆中(new出来的就是引用类型的例如String类和数组等)

在堆区中也有内存地址, 和栈区内存地址是一样的!!

1.5最简单的代码的内存

现在只需要关注 栈和堆 这来两个内存,如果没有new,则只需要关注栈区

1.6数组的内存占用

数组在栈中存放的是一串内存地址,如果直接打印也只会是一串地址数字,它的数据存放在堆中地址对应的位置,使用Arrays.toString()这个方法能将其打印出来。

二,数组的应用

2.1数组可以当方法参数

由于数组本身就是一种引用类型,因此可以直接当作方法的参数使用。

public class Demo {
    //这是一个参数为数组无返回值的方法,
    public static void count(int[] arr){
        //上面参数为形参,即形式参数,无确定的值
        for (int i = 0; i < arr.length; i++) {
            arr[i]++;
        }
        System.out.println(Arrays.toString(arr));
    }
    public static void main(String[] args) {
        int[] arr={1,2,3,4,5};//定义了一个数组
        System.out.println(Arrays.toString(arr));//打印原数组
        count(arr);//方法参数的数据类型是什么,这里调用方法的参数类型也一样,这里赋予了个实参,让其运行方法
    }
}

2.2数组当返回值类型

public class Demo2 {
    //这是一个无参返回值类型为字符串数组的方法
    public static String[] sp(){
        String[] home={"历史","灰烬","烟火","袅袅","停渡"};
        return home;//返回了一个数组
    }
    public static void main(String[] args) {
        String[] work=sp();//在主函数中调用方法后用一个相同类型(同为字符串类型的数组)的变量接住方法的返回值
        System.out.println(Arrays.toString(work));//打印数组
    }

三,引用数据类型

java的数据类型

  • 基本数据类型: 四类八种

  • 引用数据类型: 数组,类,接口 String是一个类

Java的内存,了解栈堆

方法执行进栈,执行完弹栈,new的对象进堆

  • nt[] arr = new int[4]; sout(arr) 0xac2889 就叫 对象的引用

  • 引用就是内存地址值,通过引用找到堆中的对象

  • 引用类型对象在堆中,基本类型变量在栈中

  • 引用类型方法传参时,传递是地址值

  • 基本类型方法传参时,传递是数值

  • 每个方法都是独立的

  • 方法内的变量和其他方法没关系

3.1基本类型是值的传递

基本数据类型在方法传递参数

  • 基本数据类型是数据本身(值本身)在传递

  • 且基本类型数据存在于方法的栈中

  • 方法执行完弹栈消失,方法内的变量也随之消失

将一个基本数据类型的变量的值赋给另外一个变量,操作另外一个变量不会影响原本的变量。这就是只传递值

3.2引用类型

引用类型在方法传参数时

  • 传递是对象的地址值,即引用

  • 方法接收引用后,通过引用(内存地址)找到堆中对象,改变它

  • 方法执行完弹栈,堆中对象还在

引用的数据类型在栈中存放的是一个引用地址,如果直接赋值,例如:int[] arr2=arr1,是将arr1的引用地址赋给了arr2,如果你操作arr2的数据,会直接改变引用地址对应的堆中数据,arr1的值也就改变了,

四,排序算法

排序算法

  • 冒泡排序,选择排序,插入排序

  • 快速排序,堆排序,希尔排序,归并排序

  • 桶排序,基数排序,计数排序

下面是几种简单的排序方法

4.1冒泡排序

思路:相邻的两个数据两两比较,把大数不断往后放,交换位置,依次循环排序下去。

public class Homework_effer {
    public static void main(String[] args) {
        int[] arr = {4, 1, 3, 5, 2};
        int center = 0;//交换位置的中间数
        for (int i = 0; i < arr.length-1; i++) {
            for (int j = 0; j < arr.length-1-i; j++) {
                if (arr[j]>arr[j+1]) {
                    center=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=center;
                    //两两相邻数比较,大数往后放
                }
                //不断循环,将未排序数组中的大数往后放
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}
/*i=0 0<5-1=4 true
*    j=0 0<5-1-0  true arr[0]>arr[1] 4>1 true 交换0,1  {1,4,3,5,2} j++
*    j=1 1<4  true  arr[1]>arr[2]  4>3 true  交换1,2 {1,3,4,5,2} j++
*    j=2 2<4  true  arr[2]>arr[3]  4>5 false  {1,3,4,5,2} j++
*    j=3 3<4  true  arr[3]>arr[4]  5>2 true  交换3,4 {1,3,4,2,5} j++
*    j=4 4<4 false 内层循环结束 i++
* i=1 1<4  true
*    j=0 0<5-1-1=3  true  arr[0]>arr[1]  1>3 false {1,3,4,2,5} j++
*    j=1 1<5-1-1=3  true  arr[1]>arr[2]  3>4 false {1,3,4,2,5} j++
*    j=2 2<5-1-1=3  true  arr[2]>arr[3]  4>2 true 交换2,3 {1,3,2,4,5} j++
*    j=3 3<3 false 内层循环结束 i++
* i=2 2<4  true
*    j=0 0<5-1-2=2  true  arr[0]>arr[1]  1>3 false {1,3,2,4,5} j++
*    j=1 1<5-1-1=2  true  arr[1]>arr[2]  3>2 true  交换1,2 {1,2,3,4,5} j++
*    j=2 2<5-1-1=2  false 内层循环结束 i++
* i=3 3<4 true
*    j=0 0<5-1-3=1  true  arr[0]>arr[1]  1>2 false {1,2,3,4,5} j++
*    j=1 1<1 false 内层循环结束 i++
* i=4 4<4 false 循环结束
* sout[1,2,3,4,5]
* */

4.2选择排序

public class Homework_choice {
    public static void main(String[] args) {
        int[] arr={3,2,1,5,6,7};
        int center=0;//交换位置的中间数
        for (int i = 0; i < arr.length; i++) {
            for (int j = i; j <arr.length ; j++) {
                if (arr[i] < arr[j]) {
                    center=arr[i];
                    arr[i]=arr[j];
                    arr[j]=center;
                    //将其arr[i]与其后的每个数字比较,一旦有大于它的,就让其两方换位,将选出的大数排在前面
                }
                //循环排列后面未排序的数据,一次选出其中最大数放在已排序数后面
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}

五,数组拷贝

5.1 自己手动实现

    // 数组拷贝方式1:自己实现
    public static void arrayCopyByMySelf() {
        // 将arr1数组的元素拷贝到arr2中
        int[] arr1 = {4,2,5,1,3};
​
        // 创建arr2数组
        int[] arr2 = new int[arr1.length];
        // 开始拷贝
        for (int i = 0; i < arr1.length; i++) {
            arr2[i] = arr1[i];
        }
​
        // 拷贝完,查看arr2的效果
        for (int i = 0; i < arr2.length; i++) {
            System.out.println(arr2[i] );
        }
    }

5.2 Arrays.copyOf

Arrays是jdk提供的类用来操作数组的,copyOf 用来拷贝数组的

    // 数组拷贝方式2:通过Arrays实现
    public static void arrayCopyByArrays() {
        // 将arr1数组的元素拷贝到arr2中
        int[] arr1 = {4, 2, 5, 1, 3};
​
        // 使用Arrays.copyOf方法
        // 参数1是要拷贝的数组
        // 参数2是要生成的数组的长度
        int[] arr2 = Arrays.copyOf(arr1, arr1.length-2);
​
        // 拷贝完,查看arr2的效果
        for (int i = 0; i < arr2.length; i++) {
            System.out.println(arr2[i]);
        }
​
​
    }

5.3 System.arraycopy

System是jdk提供的类,其中方法arraycopy完成数组拷贝

  // 数组拷贝方式3:通过System实现
    public static void arrayCopyBySystem() {
        // 将arr1数组的元素拷贝到arr2中
        int[] arr1 = {4, 2, 5, 1, 3};
​
        int[] arr2 = new int[arr1.length];
        /**
         * 参数1: 拷贝源数组
         * 参数2: 从源数组哪里开始拷贝(位置下标)
         * 参数3: 目的地数组
         * 参数4: 将数组放到目的地数组的哪个位置(下标)
         * 参数5: 拷贝多少个
         */
        System.arraycopy(arr1,1,arr2,1,3);
        // 拷贝完,查看arr2的效果
        for (int i = 0; i < arr2.length; i++) {
            System.out.println(arr2[i]);
        }
    }

六、数组扩容

数组本身确定是不能扩容的,此处这个"数组扩容"是指重新创建更大的数组,将之前数组元素拷贝到新数组中,接着去使用新的大数组去存储数据,感觉上是 数组扩容了.... 其实创建是了更大的新数组

package com.qf.array;
​
/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @date 2024/2/27
 * @desc 数组扩容
 */
public class Demo5 {
​
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        System.out.println("arr第一次的地址:"+arr );
        System.out.println("扩容前arr: " );
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] +" ");
        }
        System.out.println( );
​
        // 扩容
        arr = changeSize(arr);// 将返回的新数组的地址赋值给arr
        System.out.println("arr第二次的地址:"+arr );
        
        // 扩容后重写看效果
        System.out.println("扩容后arr: " );
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] +" ");
        }
    }
​
    // 这个方法可以将数组长度扩大1倍
    public static int[] changeSize(int[] a) {
        // 扩容就是创建更大数组
        int[] newArr = new int[a.length * 2];
        // 将源数组元素拷贝到新数组中
        System.arraycopy(a,0,newArr,0,a.length);
        // 返回创建的大数组
        return newArr;
    }
}

七、Arrays

Arrays是java提供一个类,专用于操作数组,常用的方法

  • copyOf() 数组拷贝

  • toString(数组); 将数组以字符串的返回

  • sort(数组); 将数组按照升序排序

// toString (重点)

  public static void main(String[] args) {
​
        int[] arr = {1,2,3,4};
        // toString(数组); 将数组以字符串形式返回
        // 方法需要通过类名.方法调用
        String s = ArSrays.toString(arr);
        System.out.println(s );
      // [1,2,3,4]
    }

// sort

       // 使用sort完成数组排序
        Arrays.sort(arr);
​
        // 排序完,再看一遍
        System.out.println(Arrays.toString(arr) );
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值