2021-11-14

java内存区域和管理机制

java运行时数据区域划分

以下大部分来自《深入理解java虚拟机》
java虚拟机在执行java程序的时候会把他分为若干区域(栈、堆、方法区),具体如下。
在这里插入图片描述

1、线程私有区域

1-1 线程与进程
1、进程:在计算机内存中的运行程序,有属于一块内存空间分配 给他,如果没记错的话好像进程切换时对应的单核和多核,就是同一时间只能处理一个进程,但是由于切换的速度快,我们好像认为它能处理多个(希望指正)。
2、线程:一个进程包含了多个线程,是cpu调度和分配的基本单位,就是线程在抢cpu的时间片,谁抢到就执行。
1-2、创建线程的两种方式
1、创建线程对象

public class CreateThread01 {
    public static void main(String[] args) {
        Thread t1 = new Thread01();
        t1.setName("线程1");

        t1.start();
        for(int i=0;i<20;i++){
            System.out.print(i+" ");
        }
//        t1.run();
        
    }
}

class Thread01 extends Thread{
    @Override
    public void run() {
        for(int i=5;i<30;i++){
            System.out.print(""+"线程1"+i+" ");
        }
    }
}

在这里插入图片描述
这里用start()开辟一个线程栈,两个线程争抢时间片,有时候是主线程(main)抢到,有时候是线程1,
如果是直接调用run(),就是调用对象方法,并没有开辟空间,所以也不是多线程

public class CreateThread01 {
    public static void main(String[] args) {
        Thread t1 = new Thread01();

        t1.run();
//        t1.start();
        for(int i=0;i<20;i++){
            System.out.print(" "+i+" ");
        }


    }
}

class Thread01 extends Thread{
    @Override
    public void run() {
        for(int i=5;i<30;i++){
            System.out.print(""+"线程"+i+" ");
        }
    }
}

在这里插入图片描述

2、继承Runable接口

public class ThreadTest03 {
    public static void main(String[] args) {
        Thread1 t1 = new Thread1();
        t1.run();
    }
}
class Thread1 implements Runnable{
    @Override
    public void run() {
        for(int i=0;i<10;i++){
            System.out.println(i);
        }
    }
}

也可以用匿名内部类的方式创建,
匿名内部类来创建

public class CreateThread02 {
    public static void main(String[] args) {
        new Runnable(){
            @Override
            public void run() {
                for(int i=0;i<6;i++){
                    System.out.println(i);
                }
            }
        }.run();
    }
}

在这里插入图片描述

1-2、程序计数器
1、程序计数器是一块内存空间,对于编译过后的字节码文件,指示程序执行到哪一行
2、每一个线程就有一个程序计数器
3、在这里插入图片描述
native方法:就不是java程序,通过java调用的非java程序
1-3 、java虚拟机栈
栈这种数据结构是先入后出,就像你往一个月饼盒里面一直向上堆月饼
每个java方法执行的时候就会有一个创建一个栈帧(一个月饼),*存储局部变量表(这个方法所需要的数据变量和对象地址),操作栈、方法出口等,*你发现要拿最底下的月饼,就需要把上面的都拿出来
这个地方有两个异常
1、outofMemoryerror
就是月饼不够放了StackOverflowError,在上面加个盒子还不够放OutOfMemoryError
1-4 本地方法栈
就是上面说的native方法就是在这个栈中(非java)

2-1 java堆
1、java堆属于线程共享区,也是java虚拟机中内存最大的区域,几乎所有的对象实例都是在这里分配 内存(简单点***对象 a = new 对象()***;这个对象就在这个区域,而栈中放的就是堆中对象的地址)
2、java堆是垃圾回收的主要地方(GC在后面几章会继续说)
3、堆内存可以不连续,也会有outOfMemory异常

3-1 方法区
在这里插入图片描述
也就是文件.class转化后的java.lang.Class对象存放的地方(这里因该是和反射有关),有了这个文件才能创建实例对象。
3-1运行时常量池
1、是方法区的一部分
2、不仅是编译后的常量放在这,运行时的也可以放这

public class CLTest01 {
    public static void main(String[] args) {
        String s = new String("boy");
        String s1 = "boy";
        System.out.println(s==s1); //false
        System.out.println(s1==s.intern());  //true
    }
}

可以看到其中s为堆中内存地址,’‘==’‘比较值,s1在常量池中,但是通过intern()使其也转化到常量池中

感觉也就这么多了,各位大佬批评指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值