zoukankan      html  css  js  c++  java
  • jvm内存管理

    由于Java程序是交由JVM执行的,所以我们在谈Java内存区域划分的时候事实上是指JVM内存区域划分。

    java虚拟机在执行java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途已及创建和销毁的时间。java虚拟机所管理的内存将会包括以下几个运行时数据区域。

    第一块:程序计数器

    多线程时,当线程数超过CPU数量或CPU内核数量,线程之间就要根据时间片轮询抢夺CPU时间资源,因此为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,如果如果执行的是JAVA方法,计数器记录正在执行的java字节码地址,如果执行的是native方法(一个Native Method就是一个java调用非java代码的接口。一个Native Method是这样一个java的方法:该方法的实现由非java语言实现),则计数器为空。

    第二块:JVM栈

    线程私有的,与线程在同一时间创建。管理JAVA方法执行的内存模型。每个方法执行时都会创建一个栈帧来存储方法的的变量表、操作数栈、动态链接方法、返回值、返回地址等信息。

    变量表存放了编译期可知的各种基本数据类型(boolean 、byte、char、short、int、float、long、double)对象引用(reference类型,它不等同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄会其他与此对象相关的位置)和returnAddress(指向了一条字节码指令的地址)。

    栈的大小决定了方法调用的可达深度(递归多少层次,或嵌套调用多少层其他方法,-Xss参数可以设置虚拟机栈大小)。栈的大小可以是固定的,或者是动态扩展的。如果请求的栈深度大于最大可用深度,则抛出stackOverflowError;如果栈是可动态扩展的,但没有内存空间支持扩展,则抛出OutofMemoryError。

    第三块:堆(Heap)

    它是JVM用来存储对象实例以及数组值的区域,可以认为Java中所有通过new创建的对象的内存都在此分配,Heap中的对象的内存需要等待GC进行回收。

     

    (1) 堆是JVM中所有线程共享的一块内存区域,在虚拟机启动时创建,在其上进行对象内存的分配均需要进行加锁,这也导致了new对象的开销是比较大的

    (2) Java堆中还可以细分为新生代和老年代。所有新创建的Object 都将会存储在新生代Yong Generation中。如果Young Generation的数据在一次或多次GC后存活下来,那么将被转移到OldGeneration。

    新生代又可进一步细分为Eden Space、survivorSpace0(s0,from space)、survivorSpace1(s1,to space)。刚创建的对象都放入Eden Space中,s0和s1都至少经过一次GC并幸存。如果幸存对象经过一定时间仍存在,则进入老年代(tenured)。

    (3) Sun Hotspot JVM为了提升对象内存分配的效率,对于所创建的线程都会分配一块独立的空间TLAB(Thread Local Allocation Buffer线程私有的分配缓冲区),其大小由JVM根据运行的情况计算而得,在TLAB上分配对象时不需要加锁,因此JVM在给线程的对象分配内存时会尽量的在TLAB上分配,在这种情况下JVM中分配对象内存的性能和C基本是一样高效的,但如果对象过大的话则仍然是直接使用堆空间分配

    (4) TLAB仅作用于新生代的Eden Space,因此在编写Java程序时,通常多个小的对象比大的对象分配起来更加高效。

    第四块:方法区域(Method Area)

    (1)在Sun JDK中这块区域对应的为PermanetGeneration,又称为持久代。

    (2)方法区域存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息,当开发人员在程序中通过Class对象中的getName、isInterface等方法来获取信息时,这些数据都来源于方法区域,同时方法区域也是全局共享的,在一定的条件下它也会被GC(回收的基本条件至少有:所有该类的实例被回收,而且装载该类的ClassLoader被回收),当方法区域需要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。

    第五块:运行时常量池(Runtime Constant Pool)

    运行时常量池是方法区的一部分,存放的为类中的固定的常量信息、方法和Field的引用信息等

    第六块:本地方法栈(Native Method Stacks)

    和虚拟机栈功能相似,但管理的不是JAVA方法,是本地方法,JVM采用本地方法栈来支持native方法的执行,此区域用于存储每个native方法调用的状态。

  • 相关阅读:
    若干排序算法简单汇总(二)
    合并两个链表的问题
    pl/sql(2)
    jQuery的DOM操作之加入元素和删除元素
    怎样优雅的研究 RGSS3 (四) 使窗体从画面边缘弹出
    Android经常使用UI组件
    在Hadoop监控页面怎样查看Hive的完整SQL
    HDU4911:Inversion
    AIX系统开启ftp服务
    JavaScript 模拟策略模式
  • 原文地址:https://www.cnblogs.com/mingyao123/p/7299921.html
Copyright © 2011-2022 走看看