Java_JVM 理解及优化

JVM 理解及优化

什么是 JDK 、JRE 、JVM ,区别与联系
  1. JDK: 是给开发者提供的开发工具箱,是给程序开发者用的。它除了包括完整的JRE(Java Runtime Environment),Java运行环境,还包含了其他供开发者使用的工具包。
  2. JRE: 普通用户而只需要安装JRE(Java Runtime Environment)来运行Java程序。而程序开发者必须安装JDK来编译、调试程序。
  3. JVM: 当我们运行一个程序时,JVM负责将字节码转换为特定机器代码,JVM提供了内存管理/垃圾回收和安全机制等。这种独立于硬件和操作系统,正是java程序可以一次编写多处执行的原因。
    区别与联系:
    1. JDK用于开发,JRE用于运行java程序 ;
    2. JDK和JRE中都包含JVM ;
    3. JVM是java编程语言的核心并且具有平台独立性。
什么是字节码?采用字节码的最大好处是什么?
  1. 先看下java中的编译器和解释器:   
    Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器。这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口。编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码执行。在Java中,这种供虚拟机理解的代码叫做’‘字节码’‘(即扩展名为 ‘’.class’’ 的文件),它不面向任何特定的处理器,只面向虚拟机。每一种平台的解释器是不同的,但是实现的虚拟机是相同的。Java源程序经过编译器编译后变成字节码,字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码送给解释器,解释器将其翻译成特定机器上的机器码,然后在特定的机器上运行。这也就是解释了Java的编译与解释并存的特点。

    Java源代码---->编译器---->jvm可执行的Java字节码(即虚拟指令)---->jvm---->jvm中解释器----->机器可执行的二进制机器码---->程序运行。

  2. 采用字节码的好处:   
    Java语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以Java程序运行时比较高效,而且,由于字节码并不专对一种特定的机器,因此,Java程序无须重新编译便可在多种不同的计算机上运行。

Java和C++的区别
- 都是面向对象的语言,都支持封装、继承和多态。
- Java不提供指针来直接访问内存,程序内存更加安全。
- Java的类是单继承的,C++支持多重继承;虽然Java的类不可以多继承,但接口可以多继承。
- Java有自动内存管理机制,不需要程序员手动释放无用内存。
JVM核心

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够“一次编译,到处运行”的原因。

  1. 基本数据类型

    • byte: //1字节有符号整数的补码 8位,最大存储数据量是255,存放的数据范围是 -128~127之间。
    • short: //2字节有符号整数的补码 16位,最大数据存储量是65536,数据范围是-32768~32767之间
    • int: //4字节有符号整数的补码 32位,最大数据存储容量是2的32次方减1,数据范围是负的2的31次方到正的2的31次方减1。
    • long: //8字节有符号整数的补码 64位,最大数据存储容量是2的64次方减1,数据范围为负的2的63次方到正的2的63次方减1。
    • float: //4字节IEEE754单精度浮点数 32位,数据范围在3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F。
    • double: //8字节IEEE754双精度浮点数 64位,数据范围在4.9e-324~1.8e308,赋值时可以加d或D也可以不加。
    • char: //2字节无符号Unicode字符 16位,存储Unicode码,用单引号赋值。
    • boolean: boolean数据类型表示一位的信息 只有true和false两个取值。

    几乎所有的Java类型检查都是在编译时完成的。上面列出的原始数据类型的数据在Java执行时不需要用硬件标记。操作这些原始数据类型数据的字节码(指令)本身就已经指出了操作数的数据类型,例如iadd、ladd、fadd和dadd指令都是把两个数相加,其操作数类型分别是int、long、float和double。虚拟机没有给boolean(布尔)类型设置单独的指令。boolean型的数据是由integer指令,包括integer返回来处理的。boolean型的数组则是用byte数组来处理的。虚拟机使用IEEE754格式的浮点数。不支持IEEE格式的较旧的计算机,在运行Java数值计算程序时,可能会非常慢。

  2. 其它数据类型

    • object: //对一个Javaobject(对象)的4字节引用
    • returnAddress //4字节,用于jsr/ret/jsr-w/ret-w指令
  3. JVM定义了控制Java代码解释执行和具体实现的五种规格,它们是:
    · JVM指令系统
    · JVM寄存器
    · JVM 栈结构
    · JVM 碎片回收堆
    · JVM 存储区

  4. JVM执行程序的过程 :

    • 加载.class文件
    • 管理并分配内存
    • 执行垃圾收集
  5. JRE(java运行时环境)包含 JVM 的 java程序的运行环境
    JVM是Java程序运行的容器,但是他同时也是操作系统的一个进程,因此他也有他自己的运行的生命周期,也有自己的代码和数据空间。
    JVM在整个jdk中处于最底层,负责与操作系统的交互,用来屏蔽操作系统环境,提供一个完整的Java运行环境,因此也叫虚拟计算机.操作系统装入JVM是通过jdk中Java.exe来完成,通过下面4步来完成JVM环境。
    1.创建JVM装载环境和配置
    2.装载JVM.dll
    3.初始化JVM.dll并挂接到JNIENV(JNI调用接口)实例
    4.调用JNIEnv实例装载并处理class类。

JVM优化核心
  1. JVM 优化主要是解决java的 GC (垃圾回收)问题。
    JVM 的使用过程中各代有,年轻带主要存放的是新创建对象。 年老代,年老代存放从年轻代存活的对象。Perm(持久代)用 于存放静态文件,如今Java类、方法等。一般持久代可以设置大一点。
  2. GC优化的目的有两个:
    1. 将转移到老年代的对象数量降低到最小;
    2. 减少full GC的执行时间;
  3. 为了达到上面的目的,一般地,你需要做的事情有:
    1、减少使用全局变量和大对象;
    2、调整新生代的大小到最合适;
    3、设置老年代的大小为最合适;
    4、选择合适的GC收集器;
垃圾回收(GC收集器): 串行收集器、并行收集器、并发收集器。
  1. 串行处理器:
    - 适用情况:数据量比较小(100M左右);单处理器下并且对响应时间无要求的应用。
    - 缺点:只能用于小型应用
  2. 并行处理器
    - 适用情况:“对吞吐量有高要求”,多CPU、对应用响应时间无要求的中、大型应用。举例:后台处理、科学计算(例如 ERP 银行系统)
    - 缺点:应用响应时间可能较长
  3. 并发处理器:
    - 适用情况:“对响应时间有高要求”,多CPU、对应用响应时间有较高要求的中、大型应用。举例:Web服务器/应用服务器、电信交换、集成开发环境。(例如互联网网站) 设置jvm堆大小 ,32bit 1.5-2G ,64bit 可以超过2G新版的JDK 每个线程的堆大小在1M改变这个线程所占用的堆大小 ,可以生成更多的线程,一般项目里线程数不能超过5000个。
什么叫GC ?

GC的全称是garbage collection,中文名称垃圾回收,是.net中对内存管理的一种功能。垃圾回收器跟踪并回收托管内存中分配的对象,定期执行垃圾回收以回收分配给没有有效引用的对象的内存。当使用可用内存不能满足内存请求时,GC会自动进行。 在进行垃圾回收时,GC的四个步骤:

  1. 垃圾回收器回首先搜索内存中的托管对象,
  2. 然后从托管代码中搜索被引用的对象并标记为有效,
  3. 接着释放没有被标记为有效的对象并收回内存,
  4. 最后整理内存将有效对象挪动到一起。

由上可见,GC是很影响性能的,所以一般说来这种事情况还是尽量少发生为好。 为了减少一些性能影响,.net的GC支持对象老化,或者说分代的概念,代是对象在内存中相对存现时期的度量单位,对象的代数或存现时期说明对象所属的代。目前.net的垃圾回收器支持三代。每进行一次GC,没有被回收的对象就自动提升一代。较近创建的对象属于较新的代,比在应用程序生命周期中较早创建的对象的代数低。最近代中的对象位于零代中。每一次GC的时候,都首先回收零代中的对象,只有在较低代数的对象回收完成后仍不能满足需求的情况下才回收较高代数的对象。

  1. JAVA中的垃圾回收机制有什么目的,什么时候进行 ?
    目的:回收堆内存中不再使用的对象,释放资源
    什么时候回收:可以手动调用gc,一般是系统等到新生代的内存区占满了又需要分配内存的时候,这个时候新生代就变成了老年代,等老年代的内存占满之后开始回收老年代所占的内存区。

  2. 优化方法
    1、多数的Java应用不需要在服务器上进行GC优化;
    2、多数导致GC问题的Java应用,都不是因为我们参数设置错误,而是代码问题;
    3、在应用上线之前,先考虑将机器的JVM参数设置到最优(最适合);
    4、减少创建对象的数量;
    5、减少使用全局变量和大对象;
    6、GC优化是到最后不得已才采用的手段;
    7、在实际使用中,分析GC情况优化代码比优化GC参数要多得多;

  3. 堆和栈的区别
    JVM是基于堆栈的虚拟机.JVM为每个新创建的线程都分配一个堆栈.也就是说,对于一个Java程序来说,它的运行就是通过对堆栈的操作来完成的。堆栈以帧为单位保存线程的状态。JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。

    1. 差异:
      1.堆内存用来存放由new创建的对象和数组。
      2.栈内存用来存放方法或者局部变量等
      3.堆是先进先出,后进后出
      4.栈是后进先出,先进后出
    2. 相同:
      1.都是属于Java内存的一种
      2.系统都会自动去回收它,但是对于堆内存一般开发人员会自动回收它
  4. 如何获取 JAVA 内存
    可以通过java.lang.Runtime 类中与内存相关方法来获取剩余的内存,总内存及最大堆内存。通过这些方法你也可以获取到堆使用的百分比及堆内存的剩余空间。
    Runtime.freeMemory() 方法返回剩余空间的字节数,
    Runtime.totalMemory() 方法总内存的字节数,
    Runtime.maxMemory() 返回最大内存的字节数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值