zoukankan      html  css  js  c++  java
  • java内存模型(线程独占部分)

    线程独占部分

    1、你了解Java的内存模型吗?

    内存简介

    有内核空间、用户空间(java是运行在用户空间上)

    32位系统---》最大的访问内存大小是4G

    62位系统---》最大的访问内存大小是512G

    背景:

    我都知道C语言下,通常将内存划分位数据段和代码段

    数据段包括堆、栈、以及静态数据区

    JVM内存模型--JDK8

    从线程的角度去看

    线程私有:程序计数器、虚拟机栈、本地方法栈(问虚拟机栈和本地方法栈的区别)

    线程共享的:元空间(metaSpace,类加载信息 OOM) ---》包括(常量池-->字面量和符合引用量)和数组、类对象 OOM

    程序计数器:

    1、当前线程所执行的字节码行号指示器(逻辑)

    2、改变计数器的值来选取下一条需要执行的字节码指令(分支,循环,跳转,异常处理,线程恢复)

    3、和线程是一对一的关系即“线程私有”

    4、对Java方法计数,如果是Native方法则计数器值位Undifined

    5、不会发生内存泄漏

    Java虚拟机栈(Stack)

    1、Java方法执行的内存模型

    2、包含多个栈帧(包含、局部变量表、操作栈、动态链接、返回地址)

    局部变量表和操作数栈的关系是什么?

    ---》局部变量表:包含方法执行过程中的所有变量(boolen ,char,long,short ,int ,float,double ...)

    操作数栈:入栈、出栈、复制、交换、产生消费变量(加减乘除的地方)

    局部变量表的数据会压入到操作数栈中,而操作数栈会进行计数,根据指令返回已计算好的数

    递归为什么会引发java.lang.StackOverflowError异常?

    -----》因为当线程执行一个方法时会创建出一个栈帧,并将栈帧压入到虚拟机栈中,当方法执行完毕的时候,就会将栈帧出栈。因此可知,当前线程所执行方法对应的栈帧必定位于虚拟机栈的顶部,

    第一,我们的递归不断调用自身,每调用一次就生成一个栈帧,

    第二,它会保存当前栈帧的状态,将它保存到虚拟机栈中,

    第三,栈帧上下文切换的时候,会切换到最新的方法栈帧中。

    由于递归过深,栈帧数超出虚拟机栈深度,就会报java.lang.StackOverflowError

    解决这个问题的方法是:1、限制递归的深度。2、用循环来替代递归

    虚拟机栈过多会引发 java.lang.OutOfMeoryError 异常?

    会的,

    public void a(){

    while(true){

     new Thread(){

       public void run(){

      while(true){}

    }}}}

    栈帧的内存是不需要通过GC去回收的,是会自动释放,是为什么呢?

    ---》因为调用方法的时候创建栈帧,调用完毕栈帧就会自动出栈。

    本地方法栈

    1、与虚拟机栈相似,主要作用域标注了native的方法(用native去修饰的方法,是用本地方法栈的,例如:forName0方法)

    程序计数器---》

    额外知识:

    内存泄漏和内存溢出的区别?

    ---》内存溢出就是程序申请内存时,没足够的内存空间被使用。

    内存泄漏是内存被程序占用了,不释放出来,导致剩余的内存越来越少。

  • 相关阅读:
    最长上升子序列问题
    多重部分和问题 (dp)
    01背包问题的延伸即变形 (dp)
    完全背包问题入门 (dp)
    最长公共子序列问题
    01背包入门 dp
    POJ 30253 Fence Repair (二叉树+优先队列)
    POJ 3069 Saruman's Army (模拟)
    [leetcode-357-Count Numbers with Unique Digits]
    [leetcode-474-Ones and Zeroes]
  • 原文地址:https://www.cnblogs.com/vingLiu/p/10650737.html
Copyright © 2011-2022 走看看