Java基础(内存分配)

 1. 常用DOS命令:
     dir(directory):列出当前目录文件及文件夹
     exit:退出dos命令行
     cls(clear screen):清屏
     ipconfig:查看ip
     ping:尝试请求某个IP或地址,并发送数据包
 2. 键盘快捷键:
     ctrl+s:保存
     ...
  3. Java的优势、特点:**跨平台**,简单性,解释性,面向对象,较高性能,分布式处理,多线程,健壮性,动态,结构中立,安全性等。
  4. 跨平台:只要在需要运行Java应用程序的操作系统上,装一个Java虚拟机(JVM Java Virtual Machine)即可,由JVM来负责JAVA程序在该系统中的运行。. 产生:1995年推出高级编程语言JAVA  James Gosling
   5. JRE(Java Runtime Environment Java运行环境)包含Java虚拟机(JVM Java Virtual Machine)和Java程序所需的核心类库等,用于运行已开发好的JAVA程序。windows系统中,bin目录下Javac.exe即为编译器,负责将Java文件转换成.class文件,Java.exe(执行器)把.class文件加载到JVM(运行环境)。.class文件针对各操作系统都一样,不同的是各系统JVM的运行机制,即各系统JVM会产生不同的0,1序列。
JDK(Java Development Kit Java开发工具包)包含JRE,还包括打包工具jar.exe等。

Java基础(内存分配)_第1张图片 java虚拟机与跨平台原理(原创分析图,转载请注明来源)

 javac.exe编译过程:源代码>词法分析器>token流>语法分析器>语法树/抽象语法树>语义分析器>注解抽象语法树>字节码生成器>JVM字节码
  6.常用快捷键

package com.ibeifeng.javase.helloworld;
public class HelloWorld {
    public static void main(String[] args) {
//        单行注释ctrl+/
        System.out.println("helloworld世界");
        /*多行注释ctrl+shift+/*/
    /*    System.out.println("helloworld世界");
        System.out.println("helloworld世界");*/
    /*ctrl+alt+l格式化代码*/
//        alt+1收缩控制框(.idea)
    }
}

7.八大基本类型与引用类型

package com.ibeifeng.javase.helloworld;
public class Int_String {
    public static void main(String[] args) {
        String name="小敏";/*引用类型*/
/*      byte:  1字节8位 -128-127
*       short 2字节16位 的取值范围-32768~32767SHORT的取值范围-32768~32767
*       int 4字节32位
*       long 8字节
*       float 4字节32位浮点数
*       double 8字节64位浮点数*/
        byte age=50;
        float workingage=3.5f;
        String interesting="乒乓";
        System.out.println("这个同学的姓名是:"+name+";\n" +
                "年龄是:"+age+";\n" +
                "工作几年:"+workingage+";\n" +
                "兴趣爱好:"+interesting+";");
        /*src——>mark——>source .idea添加资源文件*/
    }
}

8.常量的定义、变量的值交换(异或运算的运用)与算法性能比较:

常量:用final修饰,在程序执行过程中其值不可以发生改变,常量名通常大写,不同字符使用下划线分隔,只能被赋值一次,通常定义时即对其初始化。

package com.ibeifeng.javase.helloworld;

import java.util.Map;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class JavaZuoYe {
    public static void main(String[] args) {
    /*1.  int  num1 =8;
  int num2 =9;
  在不创建第三个变量情况下,将两个元素位置进行互换!!!*/
        /*(1)*/
        int num1 = 8;
        int num2 = 9;
        /* *//*容易出现精度损失*//*
        num1=num1+num2;
        num2=num1-num2;
        num1=num1-num2;
        System.out.println("num1:"+num1+"\t"+"num2:"+num2);*/
        /*(2)异或特点:二进制下
         *任何数与0异或为其本身
         * 任何数与1异或为其本身取反
         * 任何数与任意一个数异或两次为其本身
         * 任何数与它本身异或值为0
         * */
        num1 = num1 ^ num2;
        num2 = num1 ^ num2;/*num1异或num2两次为num1赋值给num2  num2=num1*/
        num1 = num1 ^ num2;/*num2异或num1两次为num2赋值给num1 num1=num2*/
        System.out.println("num1:" + num1 + "\t" + "num2:" + num2);
    /*2.键盘输入四位数字的会员卡号,使用“/”和“%”运算符分解获得会员卡各个位,上的数字
将各个位上数字求和
 */
        Scanner scan = new Scanner(System.in);
        System.out.println("请输入4位会员卡号:");
        try {
            String huiyuannum = scan.next();
            long starttime = System.nanoTime();
            Pattern pat = Pattern.compile("^[0-9]{4}$");
            Matcher mat = pat.matcher(huiyuannum);
            if (!mat.matches()) {
                System.out.println("请输入4位正整数!");
                huiyuannum = scan.next();
            }
            /*%补0,长度为4 d正整数型*/
            /*值为5555使用此公式运算速度358473*/
            Integer inthuiyuannum = Integer.valueOf(huiyuannum);
            int qianwei = (inthuiyuannum - inthuiyuannum % 1000) / 1000;
            int baiwei = (inthuiyuannum - qianwei * 1000 - inthuiyuannum % 100) / 100;
            int shiwei = (inthuiyuannum - qianwei * 1000 - baiwei * 100 - inthuiyuannum % 10) / 10;
            int gewei = inthuiyuannum - qianwei * 1000 - baiwei * 100 - shiwei * 10;
            /*值为5555使用此公式运算速度360660*/
           /* int qianwei=inthuiyuannum/1000;
            int baiwei=inthuiyuannum%1000/100;
            int shiwei=inthuiyuannum%1000%100/10;
            int gewei=inthuiyuannum%1000%100%10;*/
            System.out.println("千位数:" + qianwei + "\t百位数:" + baiwei + "\t十位数:" + shiwei + "\t个位数:" + gewei +
                    "\n会员卡号" + huiyuannum + "各位之和:" + (qianwei + baiwei + shiwei + gewei));
            long endtime = System.nanoTime();//利用System类计算程序运行时间,比较算法性能优劣
            System.out.println(endtime - starttime);
        } catch (Exception e) {
            e.getMessage();
        }
    }
}

9.变量自增、自减及先后顺序对赋值的影响

package com.ibeifeng.javase.helloworld;

import java.util.Map;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class JavaZuoYe {
    public static void main(String[] args) {
    /*1.  int  num1 =8;
  int num2 =9;
  在不创建第三个变量情况下,将两个元素位置进行互换!!!*/
        /*(1)*/
        int num1 = 8;
        int num2 = 9;
        /* *//*容易出现精度损失*//*
        num1=num1+num2;
        num2=num1-num2;
        num1=num1-num2;
        System.out.println("num1:"+num1+"\t"+"num2:"+num2);*/
        /*(2)异或特点:二进制下
         *任何数与0异或为其本身
         * 任何数与1异或为其本身取反
         * 任何数与任意一个数异或两次为其本身
         * 任何数与它本身异或值为0
         * */
        num1 = num1 ^ num2;
        num2 = num1 ^ num2;/*num1异或num2两次为num1赋值给num2  num2=num1*/
        num1 = num1 ^ num2;/*num2异或num1两次为num2赋值给num1 num1=num2*/
        System.out.println("num1:" + num1 + "\t" + "num2:" + num2);
    /*2.键盘输入四位数字的会员卡号,使用“/”和“%”运算符分解获得会员卡各个位,上的数字
将各个位上数字求和
 */
        Scanner scan = new Scanner(System.in);
        System.out.println("请输入4位会员卡号:");
        try {
            String huiyuannum = scan.next();
            long starttime = System.nanoTime();
            Pattern pat = Pattern.compile("^[0-9]{4}$");
            Matcher mat = pat.matcher(huiyuannum);
            if (!mat.matches()) {
                System.out.println("请输入4位正整数!");
                huiyuannum = scan.next();
            }
            /*%补0,长度为4 d正整数型*/
            /*值为5555使用此公式运算速度358473*/
            Integer inthuiyuannum = Integer.valueOf(huiyuannum);
            int qianwei = (inthuiyuannum - inthuiyuannum % 1000) / 1000;
            int baiwei = (inthuiyuannum - qianwei * 1000 - inthuiyuannum % 100) / 100;
            int shiwei = (inthuiyuannum - qianwei * 1000 - baiwei * 100 - inthuiyuannum % 10) / 10;
            int gewei = inthuiyuannum - qianwei * 1000 - baiwei * 100 - shiwei * 10;
            /*值为5555使用此公式运算速度360660*/
           /* int qianwei=inthuiyuannum/1000;
            int baiwei=inthuiyuannum%1000/100;
            int shiwei=inthuiyuannum%1000%100/10;
            int gewei=inthuiyuannum%1000%100%10;*/
            System.out.println("千位数:" + qianwei + "\t百位数:" + baiwei + "\t十位数:" + shiwei + "\t个位数:" + gewei +
                    "\n会员卡号" + huiyuannum + "各位之和:" + (qianwei + baiwei + shiwei + gewei));
            long endtime = System.nanoTime();//利用System类计算程序运行时间,比较算法性能优劣
            System.out.println(endtime - starttime);
        } catch (Exception e) {
            e.getMessage();
        }
    }
}

10.jd-gui.exe反编译工具的运用,对.class文件直接编译.java文件,或对jar包进行反编译。

11.逻辑运算、三目运算、if选择结构

package com.ibeifeng.javase.luojiyunsuan;

public class LuoJi_yunsuanfu {
    private int num1 = 10;
    private int num2 = 12;

    /*逻辑运算符*/
    void duanLuYuDuanLuHuo() {
        /*短路与&&,右边判断未运算,因此结果为false,num1=11*/
        System.out.println(num1++ == 11 && ++num1 == 13);
        System.out.println("num1=" + num1);
        /*短路或||左侧表达式是true时,右侧表达式不会执行*/
        /*区别于单个&单个|*/
        /*优先级:!>&&>||*/
        System.out.println(!(2 == 2) && 3 == 3);//优先级== > &&
    }

    /*三目运算:条件?表达式1:表达式2  如果条件成立执行表达式1,否则执行表达式2*/
    void sanMuYunSuan() {
        int minnum = num1 < num2 ? num1 : num2;
        System.out.println(minnum);
        /*比较三个数大小返回最小值10*/
        int num3 = 13;
        int minnum0 = num1 > num2 ? num2 : num1;
        int min = minnum0 > num3 ? num3 : minnum0;
        System.out.println(min);
        int minnum1 = num1 > num2 ? (num2 > num3 ? num3 : num2) : (num1 > num3 ? num3 : num1);//括号可去掉,优先级问题
        System.out.println(minnum1);
    }
    /*if条件语句的运用*/
    void ifTiaoJianYuJuYunYong() {
        int javaScore = 95;
        int musicScore = 85;
        if (javaScore > 90 && musicScore > 80 || javaScore == 100 && musicScore > 70) {
            /*!>&&>||*/
            System.out.println("有老师奖励!");
        } else {
            System.out.println("罚蹲马步!");
        }
        if (javaScore >= 85) {
            System.out.println("优秀!");
        } else if (javaScore >= 60) {//同时满足if条件才进入else if判断
            System.out.println("良好!");
        } else {
            System.out.println("不及格!");
        }
    }

    public static void main(String[] args) {
        LuoJi_yunsuanfu ljys = new LuoJi_yunsuanfu();
        /*()优先级最高,单目运算符!++ -- ~优先级别较高
         * =优先级最低 !>算术运算符>关系运算符>&&>||
         * 算术运算符:+ - * / %
         * 关系运算符:> < == >= <=*/
    }
}

12.for循环结构练习

package com.ibeifeng.javase.luojiyunsuan;

import java.util.Scanner;

public class XunHuanJieGou {
    public static void main(String[] args) {
        System.out.println("输入学生姓名:");
        Scanner scan0 = new Scanner(System.in);
        String name = scan0.next();
        double score = 0;
        for (int i = 0; i < 5; i++) {
            System.out.println("请输入5门功课中第" + (i + 1) + "门课的成绩:");
            double score0 = scan0.nextDouble();
            score += score0; /*a+=b:a=a+b*/
        }
        System.out.println(name + "的平均分是:" + score / 5);
        /*for循环处理循环次数确定的,
         * while do while 处理循环次数不能确定的
         * 至少执行一次的循环优先选择do while */
    }
}

13.代码结构练习

package com.ibeifeng.javase.luojiyunsuan;

import java.util.Scanner;

public class Daima_JieGou {
    void random(){
        /*随机数0-9*/
        int random = (int) (Math.random() * 10);//random=[0.0,1.0)数据为double类型 注意优先级 java.lang所有类都由Java虚拟机自动引入
        System.out.println(random);
        /*随机数20-40*/
        int random2 = (int) (Math.random() * 21) + 20;
        System.out.println(random2);
    }
    void switchFenZhi(){
        /*分支结构语句:switch可以处理区间中某个点,而if可以取一个连续的区间
         * switch结构下,先在case中寻找与表达式同一值的case,若未找到,则执行default,若没有break语句,执行完本case*/
        int mingCi = 3;
        switch (mingCi/*表达式:int short byte char Enum(枚举类型) String(jdk1.7之后版本)注意不能是double类型!!*/) {
            case 1:
                System.out.println("参加麻省理工大学组织的一个月夏令营");
                break;
            case 2:
                System.out.println("奖励电脑一部");
                break;
            case 3:
                System.out.println("奖励硬盘一个");
                break;
            default:/*通常放末尾,可以省略*/
                System.out.println("没有任何奖励");
        }
    }
    void switchString(){
        String mingCi2 = "电脑";
        switch (mingCi2/*表达式:int short byte char Enum(枚举类型) String(jdk1.7之后版本)*/) {
            case "夏令营":
                System.out.println("参加麻省理工大学组织的一个月夏令营");
                break;
            case "电脑":
                System.out.println("奖励电脑一部");
                break;
            case "硬盘":
                System.out.println("奖励硬盘一个");
                break;
            default:/*通常放末尾,可以省略*/
                System.out.println("没有任何奖励\n");
        }
    }
    void whileXunHuan(){
        /* 循环结构:while  用时2825840 2762388 2861578 2682524 2416315 2923207 2770410*/
        long starttime =System.nanoTime();
        int count=0;
        while (count<100){
            System.out.println(count+"循环性能测试");
            count++;
        }
        long endtime=System.nanoTime();
        System.out.println(endtime-starttime);
    }
    void forXunHuan(){
        /*for循环性能 用时2902057 2858660 3018023 2548690 2557078 2269352 3219686*/
        long starttime0 =System.nanoTime();
        for (int i=0;i<100;i++){
            System.out.println(i+"循环性能测试");
        }
        long endtime0=System.nanoTime();
        System.out.println(endtime0-starttime0);
    }
    void switchYunYong(){
        Scanner scan = new Scanner(System.in);
        System.out.println("MyShoping管理系统>购物结算");
        System.out.println("***********************************************");
        String str = "y";
        while (!str.equals("n")) {
            System.out.println("请选择购买的商品编号:\n1.T恤\t2.网球鞋\t3.网球拍");
            System.out.println("***********************************************");
            System.out.println("请输入商品编号:");
            String bianhao = scan.next();
            switch (bianhao) {
                case "1":
                    System.out.println("T恤\t¥988");
                    break;
                case "2":
                    System.out.println("网球鞋\t¥875");
                    break;
                case "3":
                    System.out.println("网球拍\t¥775");
                    break;
                default:
                    System.out.println("请输入正确编号!");
            }
            System.out.println("是否继续(y/n):");
            str = scan.next();
            /*输入错误的次数可能是无限次,因此这里需用while结合scanner循环判断,若为y 跳出循环进入大循环*/
            while (!str.equals("y") && !str.equals("n")) {
                System.out.println("请输入y或n!");
                str = scan.next();
            }
        }
    }
    public static void main(String[] args) {
        Daima_JieGou dj=new Daima_JieGou();
        /*do while 从上到下,先执行再判断,至少执行一次;while 先判断再执行,可以一次不执行,处理循环次数未知的循环
         * for处理循环次数固定的循环
         * for(1.初始化变量;2.条件判断;4.更新循环变量)
         *       3.代码体
         * */
    }
}

14.加法表与99乘法表(嵌套循环,按行打印)

package com.ibeifeng.javase.luojiyunsuan;

import java.util.Scanner;

public class Jiafabiao_Chengfabiao {
    void jiaFaBiao() {
        /*1题 加法表*/
        System.out.println("请输入一个值:");
        Scanner scan1 = new Scanner(System.in);
        int intr = scan1.nextInt();
        System.out.println("根据这个值可以输出以下加法表:");
        for (int i = 0; i <= intr; i++) {
            System.out.println(i + " + " + (intr - i) + " = " + intr);
        }
    }

    void ouShuSum() {
        /*2题 while循环多用于循环次数未知的情况
        1-100偶数求和*/
        int i = 1;
        int count = 0;
        while (i <= 50) {
            count += 2 * i;
            i++;
        }
        System.out.println(count);
    }

    void ouShuSum0() {
        int i = 0;
        int count = 0;
        do {
            count += 2 * i;
            i++;
        } while (i <= 50);
        System.out.println(count);
    }

    /*for循环多用于循环次数固定的循环*/
    void ouShuSum1() {
        int count = 0;
        for (int i = 0; i <= 50; i++) {
            count += 2 * i;
        }
        System.out.println(count);
    }

    /*3题 99乘法表*/
    void chengFaBiao() {
        /*4.99乘法表 按行寻找规律打印*/
        for (int i = 1; i <= 9; i++) {
            for (int j = 1; j <= i; j++) {
                System.out.print(j + " x " + i + " = " + i * j + "\t");
            }
            System.out.println();
        }
    }

    void xiangMu() {
        /*4题*/
        System.out.println("MyShopping管理系统 > 购物结算");
        System.out.println("*************************************");

        System.out.println("请选择购买的商品编号:");
        System.out.println("1.T恤\t2.网球鞋\t3.网球拍");
        double jiageTx = 555;
        double jiagewangQiu = 777;
        double jiagewangQiuPai = 999;
        String str = "y";
        while (!str.equals("n")) {
            System.out.println("*************************************");
            System.out.println("请输入商品编号:");
            Scanner scan2 = new Scanner(System.in);
            String bianhao = scan2.next();
            switch (bianhao) {
                case "1":
                    System.out.println("T恤\t¥" + jiageTx);
                case "2":
                    System.out.println("网球鞋\t¥" + jiagewangQiu);
                case "3":
                    System.out.println("网球拍\t¥" + jiagewangQiuPai);
                default:
                    System.out.println("请输入正确编号!!");
            }
            System.out.println("\n是否继续(y/n):");
            str = scan2.next();
            while (!str.equals("y") && !str.equals("n")) {
                System.out.println("请输入y/n!!");
                str = scan2.next();
            }
        }
        System.out.println("程序结束!");
    }

    public static void main(String[] args) {
        Jiafabiao_Chengfabiao jfb = new Jiafabiao_Chengfabiao();

    }
}

15.多重循环控制

package com.ibeifeng.javase.luojiyunsuan;

public class DuoChongXunHuan {
    public static void main(String[] args) {
        /*等腰三角形*/
        for (int i = 4; i >= 0; i--) {/*外层循环控制行 内层第一个循环控制空格,第二个循环控制*的个数*/
            for (int k = 0; k < i; k++) {
                System.out.print(" ");
            }
            for (int j = 0; j < 2 * (4 - i) + 1; j++) {
                System.out.print("*");
            }
            System.out.println();
        }
        /*等腰三角形 外层循环控制行,内层第一个循环控制行空格数,第二个循环控制*的数量*/
        for (int i = 0; i < 5; i++) {
            for (int k = 0; k < 4 - i; k++) {
                System.out.print(" ");
            }
            for (int j = 0; j < 2 * i + 1; j++) {
                System.out.print("*");
            }
            System.out.println();
        }
        for (int i = 0; i < 5; i++) {/*第一层循环控制行 第二层循环控制*的个数*/
            for (int j = 0; j < 5; j++) {
                System.out.print("*");
            }
            System.out.println();
        }
        for (int i = 0; i < 5; i++) {/*第一层控制行及*输出 第二层控制每行空格数*/
            for (int j = 0; j < 5 - i; j++) {
                System.out.print(" ");
            }
            System.out.print("*****");
            System.out.println();
        }
    }
}

16.数组、内存分配、增强for循环、==与equals区别:

package com.ibeifeng.javase.luojiyunsuan;

import java.util.Scanner;

public class Array_NeiCun_For {
    /*foreach增强for循环遍历数组并求和,任意输入一个整数,判断是否在数组中*/
    void forArraySum() {
        int[] arr4 = {8, 4, 2, 1, 23, 344, 12};
        int sum4 = 0;
        for (int arr : arr4) {
            System.out.print(arr + "\t");
            sum4 += arr;
        }
        System.out.println("和:" + sum4);
        Scanner scan4 = new Scanner(System.in);
        String conti = "y";
        while (!conti.equals("n")) {
            System.out.println("请任意输入一个整数:");
            int temp4 = scan4.nextInt();
            boolean flag = false;
            for (int arr : arr4) {
                if (temp4 == arr) {
                    flag = true;
                    System.out.println("arr4数列中包含此数!");
                    break;
                } else {
                    continue;
                }
            }
            if (!flag) {
                System.out.println("arr4数列中不包含此数!");
            }
            System.out.println("是否继续(y/n):");
            conti = scan4.next();
            while (!conti.equals("n") && !conti.equals("y")) {
                System.out.println("请输入y/n:");
                conti = scan4.next();
            }
        }
    }

    /*数组遍历:涉及索引引用用for(;;){}结构;其他用增强for循环结构(foreach结构)for(数组中变量类型 变量:数组){}*/
    void foreachArrays() {
        int[] scores = {1, 2, 3, 4, 5};
        for (int score : scores) {
            System.out.print(score + "\t");
        }
        /*数组是存储相同数据类型的一组数据
         *数组定义时需要给定数组长度
         * 数组越界异常
         * 创建数组时并且进行赋值需要在一条语句中执行
         * 编译异常
         * 运行异常*/
    }

    void shuzhiZiFuNeiCun() {
        String str1 = "b";
        String str2 = "b";
        System.out.println(str1 == str2);//true
        String stra = new String("b");
        String strb = new String("b");
        System.out.println(stra == strb); //false
        System.out.println(stra.equals(strb));//true
        byte a = 6;
        byte b = 6;
        System.out.println(a == b);//true
        Byte p = new Byte("5");
        /*Byte p=new Byte("5");
         *new Byte,是以Byte类为模板,在堆空间里创建一个Byte对象;
         *()表示在Byte对象创建后,立即调用Byte类的构造函数,对刚生成的对象p进行初始化;
         *Byte p表示创建了一个Byte类的引用变量,它存放在栈空间中,也就是用来指向Byte对象的对象引用;=操作符使对象
         *引用指向刚创建的堆中的Byte对象*/
        Byte q = new Byte("5");
        System.out.println(p == q);//false
        Byte s = 5;
        Byte t = 5;
        System.out.println(s == t);//true
        int[] e = {1, 2, 3};
        int[] f = {1, 2, 3};
        System.out.println(e == f);//false
    }

    public static void main(String[] args) {
        Array_NeiCun_For anf = new Array_NeiCun_For();
        /*八大基本类型存储在栈中,速度快于存储在堆中的对应包装类的实例对象:
         *其中boolean占一个二进位*/
        System.out.println(Byte.SIZE + "\t" + Byte.MAX_VALUE); //8	127
        System.out.println(Short.SIZE + "\t" + Short.MAX_VALUE);//16	32767
        System.out.println(Integer.SIZE + "\t" + Integer.MAX_VALUE);//32	2147483647
        System.out.println(Long.SIZE + "\t" + Long.MAX_VALUE);//64	9223372036854775807
        System.out.println(Float.SIZE + "\t" + Float.MIN_VALUE);//32	1.4E-45
        System.out.println(Double.SIZE + "\t" + Double.MIN_NORMAL);//64	2.2250738585072014E-308
        System.out.println(Character.SIZE + "\t" + Character.MAX_VALUE);//16	
    }
}
内存(ram)分配有三种:静态存储区、堆区和栈区,其中静态存储区主要存放静态数据、全局数据和常量 JVM(Java虚拟机)内存划分有五片:1.寄存器;2.本地方法区;3.方法区;4.栈内存;5.堆内存 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆
1.*堆区(heap):
         *位于ram,存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令);
         *jvm只有一个heap区,被所有线程共享,不存放基本类型和对象引用,只存放对象本身。
         * 堆不同于堆栈的好处是:编译器不需要知道要从堆里分配多少存储区域,也不必知道存储的数据在堆里存活多长时间,因此,
         * 在堆里分配存储有很大的灵活性。当然,为这种灵活性必须要付出相应的代码。
         *堆的优劣势:堆的优势是可以动态的分配内存大小,生存期也不必事先告诉编译器,java的垃圾收集器会自动收取这些不在使用的数
         *据,但缺点是,由于要在运行时动态分配内存,存取速度慢。
         * 一般是由程序员分配释放,若程序员不释放的话,程序结束时可能由OS回收,值得注意的是他与数据
         *结构的堆是两回事,分配方式倒是类似于数据结构的链表。
         *一种经过排序的树形数据结构,每个节点都有一个值,即二叉树,堆中某个节点的值总是不大于
         *或不小于其父节点的值堆时一棵完全二叉树,在一个摆放好元素的最小堆中,父节点元素一定比子节点
         *元素小,但对于左右节点大小没有规定;可以根据需要自己申请空间
         * 操作系统收到程序内存申请时,遍历记录内存地址的链表,寻找一个空间大于所申请空间的堆节点,然后将该节点从空闲
         * 节点链表中删除,并将该节点的空间分配给程序,大多数系统会在该内存空间首地址处记录本次分配的内存大
         * 小,以便后期正确释放内存;
         * 堆是向高地址扩展的数据结构,是不连续的内存区域;大多数编译器,函数调用时,参数是从右往左入栈的,
         * 当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令。
2.*堆栈区(stack):
         * 位于RAM,通过它的“堆栈指针”可以从处理器获得支持,堆栈指针若向下移动(向低地址扩展),则分配新的内存,
  *若向上移动,则释放这些内存;运行速度,仅次于寄存器。创建程序时候,JAVA编译器必须知道存储
  *在堆栈内所有数据的确切大小和生命周期,因为它必须生成相应的代码,以便上下移动堆栈指针,这一约束限制了程序的灵活性,
         * 每一个线程包含一个stack区,只保存基本数据类型的对象和自定义对象的引用,对象都存放在共享(heap)堆中;
         * 每个栈中的数据(基本数据类型和对象引用)都是私有的,其他栈不能访问;
         * 栈分为3部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)
         * 栈的优势劣势:存取速度比堆要快,仅次于直接位于CPU的寄存器,但必须确定的是存在stack中的数据大小与生存期必须是确定
         * 的,缺乏灵活性。单个stack的数据可以共享。
         * stack:是一个先进后出的数据结构,通常保存方法中的参数,局部变量。
         * 在java中,所有基本类型和引用类型都在stack中储存,栈中数据的生存空间一般在当前(scopes)代码块内
         * 又编译器自动分配释放,存放函数的参数值,局部变量的值等,其操作方式类似于数据结构的栈。
         * 限定仅在栈顶进行插入和删除操作的线性表;系统自动分配空间;
         * 栈区容纳常量,全局变量,静态变量,较小的区域空间应避免使用局部数组,多层次递归;
         * 栈分配内存时从栈基址向低地址扩展,即由高地址向低地址扩展
         *栈里主要存储:1.局部变量表2.操作数栈3.动态链接4.返回地址
                *1.局部变量表:存储一系列变量,这些变量都以数字数组形式存储
                *2.操作数栈:操作数栈可理解为java虚拟机栈中的一个用于计算的临时数据存储区。
                *存储的数据与局部变量表一致,含int,long,float,double,reference,returnType,操作数栈中byte,short,char
                * 压栈(bipush)前会被转为int。数据运算的地方,大多数指令都在操作数栈弹栈运算,然后结果压栈,Java虚拟机栈时方法调用
                * 和执行的空间,每个方法会封装成一个栈帧压入栈中,其中里面的操作数栈用于运算,当前线程只有当前执行的方法才会在操作数栈中调用指令
                * (可见Java虚拟机栈的指令主要取于操作数栈)
                * int类型及分别对应的压栈指令在-1~5:iconst、-128~127:bipush、-32768~32767:sipush、-2147483648~2147483647:ldc(存在于常量池)
                *3.动态链接:存在于栈里的对象在进行实例化的时,能够找到堆里面对应的类地址,并进行引用的过程即为动态链接
                *4.返回地址:方法出口记录返回地址信息,方法执行完毕,通过返回地址回到主方法原有位置,继续执行程序
3.*静态方法区:
         * 可以称之为静态区,静态区和堆很相似,其包含类类型信息、常量池、域信息、方法信息
         *          类类型信息:父类名称、类型修饰器、类类型的直接接口
         *          常量池:类方法、引用的常量信息
         *          域信息:域名称、域类型、域修饰符
         *          方法信息:方法的名称、参数、修饰符、字节码等信息
         * 其中包含的都是在程序中永远的唯一的元素
         * 跟堆一样,被所有的线程共享。方法区包含所有的class和static变量;
         *方法区又被称静态区,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
         * 运行时常量池:是方法的一部分,用于存放编译器生成的各种字面量和符号引用,者部分内容将在内加载后存放在方法区的运行时常量池中
              *静态存储(static storage):
              *这里的“静态”是指“在固定的位置”。静态存储里存放程序运行时一直存在的数据。你可用关键字
        static来标识一个对象的特定元素是静态的,但JAVA对象本身从来不会存放在静态存储空间里。
              *文字常量区:常量字符串就是放在这里,程序结束后由系统释放。
              *程序代码区:存放函数体的二进制代码。

4.寄存器(register):
        * 最快的存储区,因为它位于处理器内部,数量极其有限,它由编译器根据需求进行分配,代码不可以直接控制

             *队列:只允许在一端进行插入操作、而在另一端进行删除操作的线性表
             *非RAM存储。如果数据完全存活于程序之外,那么它可以不受程序的任何控制,在程序没有运行时也可以存在。
        *就速度来说,有如下关系: 寄存器 < 堆栈 < 堆 < 其他 ,运行类过程:方法区找到方法--堆中实例化对象--调用栈(指向堆中实例)
              *直接内存:直接内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,但这部分被频繁的使用,
              *而且也可能导致OOM异常出现。从JDK1.4开始,新加入了NIO(new Inpur/Output)并且引入了一种基于channel和Buffer的IO方式,
              *它可以使用native函数数据库直接分配堆的内存,然后通过与个存储在java堆里面的DirectByteBuffer对象作为这块内存的引用操
              *作,这样能在一些场景中显著提高性能,因为避免了在Java堆和native堆中来回复制数据

5.本地方法区:在本地方法栈中执行非java语言编写的代码,例如C或者C++
Java基础(内存分配)_第2张图片 内存分配原理(原创分析图,转载请注明来源)
Java基础(内存分配)_第3张图片 JVM内存分配原理(原创分析图,转载请注明出处~)

 

Java基础(内存分配)_第4张图片 JAVA内存模型(原创分析图,转载请注明出处~)

 

volatile的特殊规则是:

  1. read、load、use动作必须连续出现。
  2. assign、store、write动作必须连续出现。

volatile关键字修饰的变量看到的随时是自己的最新值

 

Java基础(内存分配)_第5张图片

 

*==与equals区别:

*==比较的是两个对象的地址; 

*==比较八大基本数据类型(比较元素内存地址)

*equals比较的是两个对象的内容

* equals比较元素内容(字符串)

17.数组、break、continue、return

package com.ibeifeng.javase.luojiyunsuan;

import com.sun.org.apache.xpath.internal.operations.Bool;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

import java.util.Scanner;

public class ShuZu_BreakContinue_Return {
    void qiuHe() {
        int sum = 0;
        int i = 1;
        out:
        while (i < 50) {
            sum += i;
            i++;
            if (sum > 30) {
                /* break中断外部循环*/
                break out;
            }
        }
        System.out.println(sum);
    }

    /*continue跳过本次循环*/
    void continueTiaoGuo() {
        int sum0 = 0;
        out:
        for (int j = 1; j <= 10; j++) {
            if (j % 2 == 0) {
                sum0 += j;
            } else {
                continue out;
            }
        }
        System.out.println(sum0);
    }

    void arrays() {
         /* 变量:在内存中划出一块空间
           数组在内存中划出一串连续的空间*/
        int[] a = new int[5]; /*定义数组长度*/
        int b[] = {5, 4, 3, 2, 1};
        int c[][] = new int[3][5];
        int d[] = new int[]{8, 9};//注意这里不能给定长度
        /*数组的初始值:
         * 整型数组初始值都为0
         * 浮点型数组初始值都为0.0
         * char型初始值为空格
         * boolean类型初始值为false
         * String类型数组初始值为null
         * 引用数据类型数组初始值都为null
         * 数组越界异常:ArrayIndexOutOfBoundsException*/
        int[] scores = {60, 81, 90, 70, 85};
        int sum8 = 0;
        for (int i = 0; i < scores.length; i++) {
            sum8 += scores[i];
        }
        System.out.println(sum8);
    }

    public static void main(String[] args) {
        /* return结束方法并返回值*/

        /*debug 区分debugger控制台与controller控制台 */
        /*ALT+ENTER返回变量的类型*/
        ShuZu_BreakContinue_Return sbcr = new ShuZu_BreakContinue_Return();

    }
}

 

18.循环结构使用场景

package com.ibeifeng.javase.luojiyunsuan;

import java.util.Scanner;

public class XunHuan_jiegou {
    public static void main(String[] args) {
        System.out.println("输入学生姓名:");
        Scanner scan0 = new Scanner(System.in);
        String name = scan0.next();
        double score = 0;
        for (int i = 0; i < 5; i++) {
            System.out.println("请输入5门功课中第" + (i + 1) + "门课的成绩:");
            double score0 = scan0.nextDouble();
            score += score0; /*a+=b:a=a+b*/
        }
        System.out.println(name + "的平均分是:" + score / 5);
        /*for循环处理循环次数确定的,
         * while do while 处理循环次数不能确定的
         * 至少执行一次的循环优先选择do while */
    }
}

19.面试练习题01:数组遍历与包含关系确认

package com.ibeifeng.javase.luojiyunsuan;

public class MianShiTi_LianXi01 {
    void arrayContains() {
        /*第三题:int[] a int[] b 判断b 数组是否为a数组的子串*/
        int[] a = {7, 4, 3, 7, 7};
        int[] b = {7, 7, 9};
        int flag = 0;
        if (a.length >= b.length) {
            for (int b0 : b) {
                in:
                for (int a0 : a) {
                    if (a0 == b0) {
                        flag++;
                        break in;
                    }
                }
            }
            if (flag == b.length) {
                System.out.println("b数组是a数组的字串!");
            } else {
                System.out.println("b数组不是a数组的字串!");
            }
        } else {
            System.out.println("b数组不是a数组的字串!");
        }
    }

    void chengFaBiao() {
        /*第一题:99 乘法表 编写*/
        for (int i = 1; i <= 9; i++) {
            for (int j = 1; j <= i; j++) {
                System.out.print(j + " X " + i + " = " + i * j + "\t");
            }
            System.out.println();
        }
    }

    void maxArray() {
        /*第二题:int[] a = {1,3,16,12,361}使用代码将数组a 中最大值求出*/
        int[] a = {1, 3, 16, 12, 361};
        int max = 0;
        for (int b : a) {
            if (b > max) {
                max = b;
            }
        }
        System.out.println("数组a中最大值为:\t" + max);
    }

    public static void main(String[] args) {
        MianShiTi_LianXi01 mianshi = new MianShiTi_LianXi01();

    }
}

20.插入排序、冒泡排序、二维数组及部分测试题

package com.ibeifeng.javase.luojiyunsuan;

import java.util.Arrays;
import java.util.Scanner;

public class ChaRu_MaoPao_Arrays {
    /*排序:性能347168*/
    void maoPao(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {    /*外层让第一个数与内层循环所有数比较,若大,则交换位置,第一次内层循环结束,第一个值最大*/
            for (int j = i + 1; j < arr.length; j++) {/*内层循环通过j与i关系,控制比较的范围,只比较未作比较的地方,最终实现从大大小排序*/
                if (arr[j] > arr[i]) {
                    arr[j] = arr[j] ^ arr[i];
                    arr[i] = arr[j] ^ arr[i];
                    arr[j] = arr[j] ^ arr[i];
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }

    /*2.优化后冒泡排序  先比较大小,再交换位置  性能551748 */
    void maoPao0(int[] arr) {
        /*外层循环控制循环次数*/
        out:
        for (int i = 0; i < arr.length - 1; i++) {
            boolean flag = true;
            /*内层循环控制相邻两个元素比较,相邻元素若满足条件,则进行位置交换,从第2个元素起,相邻元素至少判断2次(与前一个数的比较与后一数的比较),
             * 因此内层循环结束,最后一个值必然为最小值*/
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j + 1] > arr[j]) {
                    arr[j] = arr[j] ^ arr[j + 1];
                    arr[j + 1] = arr[j] ^ arr[j + 1];
                    arr[j] = arr[j] ^ arr[j + 1];
                    flag = false;/*内层循环第一次循环,未作数据交换,说明为顺序结构*/
                }
            }
            if (flag) {
                break out;/*对顺序结构直接中断整个循环体*/
            }
        }
        System.out.println(Arrays.toString(arr));
    }

    /*1.插入排序
     *插入数据,并使新的数组结构呈降序排序
     *将成绩保存在数组中,通过比较找到插入位置,该位置元素往后移一位,插入新成绩
     * 从中间插入或添加到最后一位后排序*/
    void chaRupaixu() {
        int[] score0 = {99, 82, 85, 63, 60};
        /*降序排序*/
        int tmp = 0;
        for (int i = 0; i < score0.length - 1; i++) {
            for (int j = i + 1; j < score0.length; j++) {
                if (score0[i] < score0[j]) {
                    tmp = score0[i];
                    score0[i] = score0[j];
                    score0[j] = tmp;
                }
            }
        }
        /*将已排序数组赋值给新的数组,并在新数组尾数添加一个空值用于挪出插入数据的位置*/
        int[] score1 = new int[score0.length + 1];
        for (int i = 0; i < score0.length; i++) {
            score1[i] = score0[i];
        }
        int num = 60;
        for (int i = 0; i < score1.length - 2; i++) {
            if (score1[i] <= num && num <= score1[i + 1]) {
                for (int j = score1.length - 2; j >= i + 1; j--) {
                    score1[j + 1] = score1[j];
                }
                score1[i + 1] = num;/*先将插入位置及之后所有数据向后移动一位,再将要插入数据插到空出的位置*/
            } else if (num <= score1[score1.length - 2]) {/*需要考虑给定的插入数据比数组尾数都小的情况,那么直接将数据插入*/
                score1[score1.length - 1] = num;
            }
        }
        System.out.println(Arrays.toString(score1));
    }
    /*编写程序,键盘录入年份,判断给定的某个年份是否是闰年。闰年的判断规则如下:
    a.若某个年份能被4整除但不能被100整除,则是闰年
    b.若某个年份能被400整除,则也是闰年。*/
    void runNian() {
        Scanner scan = new Scanner(System.in);
        int year = scan.nextInt();
        if (year % 4 == 0 && !(year % 100 == 0)) {
            System.out.println(year + "是闰年!");
        } else if (year % 400 == 0) {
            System.out.println(year + "是闰年!");
        } else {
            System.out.println(year + "不是闰年!");
        }
    }
    /*遍历二维数组并求和练习*/
    void xiangMu_erWeishuzu() {
        int[][] scores = new int[3][5];
        for (int n = 1; n <= 3; n++) {
            System.out.println("*******************第" + n + "个班*******************");
            for (int m = 1; m <= 5; m++) {
                Scanner scan = new Scanner(System.in);
                System.out.println("请输入第" + m + "个学生的成绩:");
                int score = scan.nextInt();
                scores[n - 1][m - 1] = score;
            }

        }
        System.out.println("*******************成绩统计*******************");
        int[][] sum = new int[3][1];
        for (int i = 0; i < scores.length; i++) {
            for (int j = 0; j < scores[i].length; j++) {
                sum[i][0] += scores[i][j];
            }
            System.out.println((i + 1) + "班总成绩:\t" + sum[i][0]);
        }
    }
    /*我国最高山峰是珠穆朗玛峰:8848m,我现在有一张足够大的纸张,厚度为:0.01m。折叠多少次,就可以保证厚度不低于珠穆朗玛峰的高度?*/
    void zheDieCishu() {
        int n = 0;
        for (int i = 2; i >= 2; i *= 2) {
            n++;/*先计数,再判断是否满足大于等于8848的条件,满足则中断循环*/
            if (0.01 * i >= 8848) {
                break;
            }
        }
        System.out.println("折叠" + n + "次");
    }
    void zheDieCishu0() {
        int count=0;
        double height=0.01;
        while (height<=8848){
            height*=2;
            count++;
        }
        System.out.println(count);
    }
    /*3.Arrays:
                二维数组从内存分配原理的角度讲,只有一维数组*/
    void arrayFangFa(){
        int[]a={1,2,3};
        int[]b={1,3,2,77,9};
        int[]c={9,4};
        System.out.println(Arrays.equals(a,b));/*源码*/
        /*将数组所有值替换为指定值*/
        Arrays.fill(c,5);
        System.out.println(Arrays.toString(c));
        /*将数组按升序排序*/
        Arrays.sort(b);
        System.out.println(Arrays.toString(b));
        /*查看数组中某个字符位置*/
        System.out.println(Arrays.binarySearch(b,77));/*查看源码*/
        /*复制数组给到另一个数组变量*/
        int[] copya = Arrays.copyOf(a, a.length);
        System.out.println(Arrays.toString(copya));
    }

    /*写一个功能实现输出数组中元素为奇数的数据。*/
    void arrJishu(int[] arr) {
        for (int i : arr) {
            if (!(i % 2 == 0)) {
                System.out.print(i + "\t");
            }
        }
    }
    /*计算1-100奇数的总和*/
    void sumJishu() {
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
            if (!(i % 2 == 0)) {
                sum += i;
            }
        }
        System.out.println(sum);
    }
    /*定义一个方法,接收一个数组,找出该数组的最大值,并在函数中直接输出,不用返回*/
    void maxArr(int[] arr) {
        int max = 0;
        for (int i : arr) {
            if (max < i) {
                max = i;
            }
        }
        System.out.println("\n" + max);
    }

    public static void main(String[] args) {
        ChaRu_MaoPao_Arrays cma = new ChaRu_MaoPao_Arrays();
/*
        * *******************第1个班*******************
请输入第1个学生的成绩:
63
请输入第2个学生的成绩:
95
请输入第3个学生的成绩:
86
请输入第4个学生的成绩:
77
请输入第5个学生的成绩:
59
*******************第2个班*******************
请输入第1个学生的成绩:
100
请输入第2个学生的成绩:
63
请输入第3个学生的成绩:
69
请输入第4个学生的成绩:
74
请输入第5个学生的成绩:
99
*******************第3个班*******************
请输入第1个学生的成绩:
82
请输入第2个学生的成绩:
91
请输入第3个学生的成绩:
67
请输入第4个学生的成绩:
52
请输入第5个学生的成绩:
100
*******************成绩统计*******************
1班总成绩:	380
2班总成绩:	405
3班总成绩:	392*/
    }
}

 

package com.ibeifeng.javase.mianxiangduixiang;

import java.util.Arrays;

public class Shuzu {
    int[] a = {1, 2, 3, 4};

    void setA() {
        int[] b = {2, 3, 4, 5, 6, 7};
        this.a = new int[b.length];
        for (int i = 0; i < b.length; i++) { //  //注意增强for循环:之前变量代表数组中的值
            a[i] = b[i];
        }
    }

    public static void main(String[] args) {
        Shuzu shuzu = new Shuzu();
        shuzu.setA();
        System.out.println(Arrays.toString(shuzu.a));
    }
}

️ 不要忘记留下你学习的脚印 [点赞 + 收藏 + 评论]

一切看文章不点赞都是“耍流氓”,嘿嘿ヾ(◍°∇°◍)ノ゙!开个玩笑,动一动你的小手,点赞就完事了,你每个人出一份力量(点赞 + 评论)就会让更多的学习者加入进来!非常感谢! ̄ω ̄=

面向对象

技术交流请加微信,备注CSDN~~(文章原创,不免出现错误或不足,欢迎指正~)

tchongyu

 

你可能感兴趣的:(Java,java,内存分配)