zoukankan      html  css  js  c++  java
  • 1.Java虚拟机内存模型

    前言

    JAVA和C++之间有着一堵由内存的动态分配垃圾收集技术所围成的“高墙“;

    1.概述

    JAVA虚拟机有自动的内存管理机制,程序员不用为每一个对象写new/delete代码进行内存的分配和回收,不容易出现内存的泄漏和溢出,但是还是很有必要学习JAVA虚拟机的内存模型和垃圾回收算法,否则出现内存泄漏和溢出的时候将会很难处理。

    内存泄漏:

    内存溢出:

    2.JAVA虚拟机运行时内存区域

            JAVA运行时数据区分为线程独享和线程共享两大部分,这些内存区域各有各的用途,内存的创建和销毁时间都各不相同。

    图一.JAVA虚拟机运行时数据区

    • 程序计数器
        • 线程独享,可以看作是当前线程执行指令的行号指示器,因为JAVA虚拟机中的各个线程的并发执行是交替进行的,每个处理器在相同的时间内只能运行一个线程,所以每个线程的程序计数器,程序计数器时唯一一个不会出现内存溢出的运行时数据区。
        • 异常情况:无
    • 虚拟机栈
        • 线程独享,JAVA方法执行的内存模型,每个函数的执行都会创建一个栈帧,每个方法的执行,其实是一个栈帧在虚拟机栈中入栈到出栈的过程。虚拟机栈存储局部变量表(基本类型局部变量,ReturnAddress、对象引用)、操作数栈、方法出口等。  
        • 异常情况:
        • 1.线程请求的栈深度大于虚拟机所允许的深度,stackoverflow
        • 2.虚拟机栈内存扩展失败,outofmemory
    • 本地方法栈
        • 线程独享,类似于虚拟机栈,只是这里的方法是native方法,常见的native方法,eg:原生的hashcode函数
        • 异常情况:
        • 1.stackoverflow
        • 2.outofmemory   
        • 线程共享,用途为存放对象实例
        • 异常情况:
        • 1.outofmemory    
    • 方法区(永久代)
        • 用于存储类加载相关信息(class对象、字节码)、运行时常量池、静态变量。    
        • 异常情况:
        • 1.outofmemory

    3.JAVA堆上对象的创建、布局和访问过程

    3.1.对象的创建-----虚拟机角度

    创建对象的方式有很多种:1.new关键字  2.工厂方法  3.静态工厂方法 4.反射机制 Class.newInstance() 5.对象clone()等

    • 虚拟机角度对象的创建  
    • 1.检查类是否被加载、验证、准备和解析过。
    • 2.执行类加载过程
    • 3.为对象分配内存
        • 3.1假设JAVA堆中的内存的分配是绝对规整的,使用过的内存放在一边,没有使用过的内存放在一边,那么内存的分配使用“指针碰撞”的方式。
        • 3.2如果JAVA堆中的内存分配不是绝对规整的,那么使用“空闲列表”的方式进行内存的分配。
          • 除了分配方式之外,还需要考虑内存分配的线程安全性解决方式如下
            • a.对内存分配的动作进行同步处理
            • b.TLAB(Thread Local Allocation Buffer),先给每个线程分配堆内存,之后每个线程使用自己的TLAB为对象分配内存。
    • 4.必要的设置,对象属于哪个类的实例,找到对象元数据(Class对象??),对象的哈希码,对象的GC年代等。

    3.2.对象的布局

    • 对象的内存区间分为三个部分:
    • 1.对象头    
    • 2.实例数据
    • 3.对齐填充------对象必须是8字节的整数倍

    3.3.对象的访问

    • 直接指针--优点速度快,节约了句斌池所占的空间。
    • 句柄池----引用对象发生改变的时候,不用改变reference指向的句柄,而是可以直接改变句柄的指向。

    4.JAVA虚拟机内存溢出实战

    • JAVA堆溢出
    • 核心代码:
    • List<Object> list=new ArrayList<Object>();
      while(true){
            list.add(new Object());  
      }
    • JAVA虚拟机栈溢出
    • 核心代码:
    • public void stackLeak(){
             stackLeak();
      }//stackOverflow
      
    • Java虚拟机内存溢出
    • 核心代码:
    • while(true){
              Thread thread=new Thread(new Runnable(){
                         while(true){
                         }
                    } 
              );    
      }
    • JAVA虚拟机方法区溢出
    • 核心代码:
    • List list=new ArrayList();
      int i=0;
      while(true){
            list.add(new String(i++).intern());
      }
      

     

  • 相关阅读:
    第四章 处理器体系结构
    第四节、程序的机器语言
    第三节 信息的表示和处理
    app
    你只是看起来很努力
    tap news:week5 0.0 create react app
    28.week4
    ubuntu去除带锁文件的锁 sudo chown 用户名 目标文件夹/ -R
    26.如何使用python操作我们自己创建的docker image呢?
    25.week4 docker build 也就是创建自己的image 上传image到dockerhub 从dockerhub下载images
  • 原文地址:https://www.cnblogs.com/yangyunnb/p/6379900.html
Copyright © 2011-2022 走看看