前几天公司的郑大晔校上,XXX同事做了JVM的Session,于是趁端午节放假的功夫,研究了一些JVM相关的知识。

在Java生态系统中,JVM占据至关重要的作用,就像一个适配器,它向编程语言(主要是Java)屏蔽了操作系统的差异,所以实现了“一次编写,到处运行”的理想;同时也向操作系统屏蔽了编程语言之间的差异,能让Java、Clojure、JRuby、JPython、Groovy等高级语言运行于Java虚拟机之上;可以说,JVM完全实现了跨系统跨语言的支持。

如果以Jeffery Richter的眼光看来,JVM在某种程度上,也应该算作是它自己的操作系统,因为它有自己的内存管理器、自己的安全系统、自己的文件加载器,自己的错误处理机制、自己的线程处理模型;总之一句话,JVM是相当的牛B。

(跑题一下,正所谓“理想很丰满、现实很骨干”,iOS上根本无法运行JVM,原因很简单,苹果公司禁止在iOS中使用及时编译;这也是为什么Mono在开发完成后也只得将源代码直接编译为Native Code;可能很多人会说,我们不能用边解释边执行的方式在iOS上运行Java程序么?至于这个问题,下面再谈......归根结底,“一次编写,到处运行”有时候并不是你想像的那样牛X)。

言归正传,自Java诞生以来,历史上曾产生过很多优秀的虚拟机,最出名的要数Sun公司的Classic VM和HotSpot VM,前者在JDK1.1和1.2时使用得比较多,它是用纯解释器的方式来执行Java代码,一发布后便引起了极大的轰动,当然也为Java博得了“Java语言很慢”的“美誉”;但随着虚拟机技术的不断发展和理论的不断完善,在JDK1.2之后Sun公司发布了新一代的虚拟机-----HotSpot VM,开发人员在这款虚拟机中内置了JIT编译器并使之具有了热点代码探测能力,及如果一段Java方法被调用次数达到了一定程度之后,就会被视为热点代码并交给JIT编译器及时编译成本地代码,以提高运行速度。

JVM的一个重要的特征就是它的自动内存管理机制,在执行一段Java代码的时候,会把它所管理的内存划分成几个不同的数据区域,其中包括:

  1. 程序计数器,众所周知,JVM的多线程是通过线程轮流切换并分配CPU执行时间的方式来实现的,那么每一个线程在切换后都必须记住它所执行的字节码的行号,以便线程在得到CPU时间时进行恢复,这个计数器用于记录正在执行的字节码指令的地址,这里要强调的是“字节码”,如果执行的是Native方法,那么这个计数器应该为null;
  2. Java计算栈,可以说整个Java程序的执行就是一个出栈入栈的过程,JVM会为每一个线程创建一个计算栈,用于记录线程中方法的调用和变量的创建,由于在计算栈里分配的内存出栈后立即被抛弃,因此在计算栈里不存在垃圾回收,如果线程请求的栈深度大于JVM允许的深度,会抛出StackOverflowError异常,在内存耗尽时会抛出OutOfMemoryError异常;
  3. Native方法栈,JVM在调用操作系统本地方法的时候会使用到这个栈;
  4. Java堆,由于每个线程分配到的计算栈容量有限,对于可能会占据大量内存的对象,则会被分配到Java堆中,在栈中包含了指向该对象内存的地址;对于一个Java程序来说,只有一个Java堆,也就是说,所有线程共享一个堆中的对象;由于Java堆不受线程的控制,如果在一个方法结束之后立即回收这个方法使用到的对象,并不能保证其他线程是否正在使用该对象;因此堆中对象的回收由JVM的垃圾收集器统一管理,和某一个线程无关;在HotSpot虚拟机中Java堆被划分为三代:
    • 新生代,正常情况下新创建的对象会被分配到新生代,但如果对象占据的内存足够大以致超过了新生代的容量限制,也可能被分配到老年代;新生代对象的一个特点是最新、且生命周期不长,被回收的可能性高;
    • 老年代,除了上述所说的大对象会被直接分配在老年代之外,一个在新生代的对象历经多次垃圾回收之后,也会被直接拷贝至老年代,当然老年代的容量要比新生代大得多;
    • 永久代,永久代并不存储对象,而是存储一些JVM加载的类信息、常量、静态变量、JIT编译后生成的代码等,JVM也会在内存空间不足的情况下对永久代进行回收;
  5. 直接内存,自JDK1.4新加入NIO类之后,Java程序便可以使用Native函数库直接分配堆外内存,然后通过一个存储在堆中的DirectByteBuffer对象来对这块内存的引用进行操作;直接内存的容量不受堆容量的限制。

JVM内存管理的更多相关文章

  1. JVM内存管理------垃圾搜集器参数精解

    本文是GC相关的最后一篇,这次LZ只是罗列一下hotspot JVM中垃圾搜集器相关的重点参数,以及各个参数的解释.废话不多说,这就开始. 垃圾搜集器文章传送门 JVM内存管理------JAVA语言 ...

  2. Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收

    很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确 ...

  3. JVM内存管理(二)

    JVM内存管理          JVM在执行java程序的过程中,会把内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖 ...

  4. JVM内存管理及垃圾回收

    一.JVM内存的构 Java虚拟机会将内存分为几个不同的管理区,这些区域各自有各自的用途,根据不同的特点,承担不同的任务以及在垃圾回收时运用不同的算法.总体分为下面几个部分: 程序计数器(Progra ...

  5. 现代JVM内存管理方法的发展历程,GC的实现及相关设计概述(转)

    JVM区域总体分两类,heap区和非heap区.heap区又分:Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分: ...

  6. java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)

    Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收集(Garbage Collection,下文简称GC),大部分人都把这项 ...

  7. java虚拟机学习-JVM内存管理:深入Java内存区域与OOM(3)

    概述 Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝又 ...

  8. Java的内存 -JVM 内存管理

    一.综述 如果你学过C或者C++,那么你应该感受过它们对内存那种强大的掌控力.但是强大的能力往往需要更强大的控制力才能保证能力不被滥用,如果滥用C/C++的内存管理那么很容易出现指针满天飞的情况,不出 ...

  9. JVM内存管理及垃圾回收【转】

    很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确 ...

  10. 你应该这样理解JVM内存管理

    在进行Java程序设计时,一般不涉及内存的分配和内存回收的相关代码,此处引用一句话: Java和C++之间存在一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外的人想进去,墙里面的人想出来 ,个人从这 ...

随机推荐

  1. git revert和git reset的区别

    git revert 是撤销某次操作,此次操作之前的commit都会被保留 git reset 是撤销某次提交,但是此次之后的修改都会被退回到暂存区 具体一个例子,假设有三个commit, git s ...

  2. jquery插件学习之元素顶部悬浮

    jquery插件的学习: HTML部分及应用 <!DOCTYPE html> <html> <head> <meta charset="utf-8& ...

  3. C++标准库 -- tuple

    头文件:<tuple> 可访问属性: 无(用get方法来访问数据) 可访问方法: swap(tuple) 和另外一个tuple交换值 其他相关方法: swap(t1, t2) 交换两个tu ...

  4. PHP 获取当天 凌晨 时间戳常用代码

    echo strtotime(date('Y-m-d')); 获取明天凌晨的时间戳代码:echo strtotime(date('Y-m-d',strtotime('+1 day'))); 附上测试代 ...

  5. Mac 安装activate-power-mode atom

    Mac 安装activate-power-mode atom 标签: atommac 2015-12-02 14:53 308人阅读 评论(0) 收藏 举报  分类: git(2)  版权声明:本文为 ...

  6. GIT-查看本地html帮助文档

    GIT安装后可以直接在命令行中通过指令调取本地html帮助文档如下所示: 格式: git help remote--git help 指令名称 git help remote 显示结果 获取branc ...

  7. iOS webView与H5的交互(返回页面的处理)

    摘自:http://blog.csdn.net/qq_29284809/article/details/50548413 调用 H5页面的同名返回方法(必须保证名字一致)!!!

  8. WP8.1 和UWP 如何使用下载网页的上的音频 并保存

    WP8.1: private async Task<StorageFile> GetVoiceData() { HttpClient httpclient = new HttpClient ...

  9. 就publish/subscribe功能看redis集群模式下的队列技术(一)

    Redis 简介 Redis 是完全开源免费的,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中 ...

  10. Spring boot学习一

    SSM框架:Spring+SpringMVC+MyBatisSpring Boot一.pom文件:pom.xml中添加:    <!--spring-boot-starter-web提供了对we ...