1.整型数和浮点型数的表示

  原码:第一位为符号位(0为正数,1为负数)。

  反码:符号位不动,源码取反。

  正数补码:和原码相同。

  负数补码:符号位不动,反码加1。

  例如5的二进制表示可以是00000101,-6的表示:原码10000110,反码11111001,补码11111010,-1的表示:10000001,反码11111110,补码11111111

  补码的好处:0的表示唯一,数的符号位可以同数值部分作为一个整体参与运算,可以直接做加法,减法运算可以用加法来实现,即用求和来代替求差。

  例如:0的表示:正数00000000,负数10000000。

     -6+5                -4+5

       11111010         11111100

+00000101       +00000101

= 11111111      = 00000001

  打印正数的二进制表示

int a=-6;
for(int i=0;i<32;i++){
int t=(a & 0x80000000>>>i)>>>(31-i);
System.out.print(t);
}

  IEEE754浮点数的表示格式:s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm

符号位(1)  指数位(8) 尾数(23)

          e全0 尾数附加位全0,否则尾数附加位为1

          s*m*2(e-127)

  例如:1 10000001 0100000000000000000000

  -1*2(129-127)*(20+2-2) = -5

  将单精度浮点数转成IEEE754二进制表示的代码示例:

package work.jvm;
public class ftob {
public static final int BITS = 32;
public static void main(String[] args) {
int i;
ftob ftb = new ftob();
float f = -9f;
System.out.println("float is:" + f);
int[] b = ftb.printBinaryFloat(f);
System.out.print("Binary is:");
for(i = 0; i < BITS; i++){
System.out.print(b[i]);
}
}
public int[] printBinaryFloat(float f){
int j;
int r[] = new int[32];
int temp = Float.floatToIntBits(f);
for(j = BITS-1; j >= 0; --j){
r[BITS-1-j] = ((temp>>j)&0x01);
}
return r;
}
}

2.jvm运行机制

  JVM启动过程:

  

  JVM基本结构:

  

  (1)PC寄存器:每个线程拥有一个PC寄存器,在线程创建时创建,指向下一条指令的地址,执行本地方法时,PC的值为undefined。

  (2)方法区:保存装载的类信息,如i类型的常量池、字段和方法信息、方法字节码,通常和永久区(Perm)关联在一起。

  (3)java堆:和程序开发密切相关,应用系统对象都保存在Java堆中,所有线程共享Java堆,对分代GC来说,堆也是分代的,GC的主要工作区间。

  

  (4)java栈:线程私有,栈由一系列帧组成(因此Java栈也叫做帧栈),帧保存一个方法的局部变量、操作数栈、常量池指针,每一次方法调用创建一个帧,并压栈。

    栈上分配:小对象(一般几十个bytes),在没有逃逸的情况下,可以直接分配在栈上,直接分配在栈上,可以自动回收,减轻GC压力,大对象或者逃逸对象无法栈上分配。

  (5)堆、栈、方法区交互:

public class AppMain
//运行时, jvm 把appmain的信息都放入方法区
{
public static void main(String[] args)
//main 方法本身放入方法区。
{
Sample test1 = new Sample("测试1");
//test1是引用,所以放到栈区里, Sample是自定义对象应该放到堆里面
Sample test2 = new Sample("测试2");
test1.printName(); test2.printName();
}
}
public class Sample
//运行时, jvm 把appmain的信息都放入方法区
{
private name;
//new Sample实例后,name引用放入栈区里,name对象放入堆里
public Sample(String name)
{
this.name = name;
}
//print方法本身放入 方法区里。
public void printName()
{
System.out.println(name);
}
}
 
3.jvm配置参数
  (1)Trace跟踪参数 
  -verbose:gc
  -XX:+printGC

可以打印GC的简要信息
  -XX:+PrintGCDetails 打印GC详细信息
  -XX:+PrintGCTimeStamps 打印CG发生的时间戳
  -Xloggc:log/gc.log 指定GC log的位置,以文件输出
  -XX:+TraceClassLoading 监控类的加载
  -XX:+PrintClassHistogram 按下Ctrl+Break后,打印信息 分别显示:序号、实例数量、总大小、类型
  (2)堆分配参数
  -Xmx –Xms 指定最大堆和最小堆,例如:-Xmx20m -Xms5m
  -Xmn 设置新生代大小
  -XX:NewRatio 新生代(eden+2*s)和老年代(不包含永久区)的比值,比如4 表示新生代:老年代=1:4,即年轻代占堆的1/5。
  -XX:SurvivorRatio 设置两个Survivor区和eden的比,比如8表示 两个Survivor :eden=2:8,即一个Survivor占年轻代的1/10。
  -XX:+HeapDumpOnOutOfMemoryError,OOM时导出堆到文件。
  -XX:+HeapDumpPath 导出OOM的路径。
  -XX:OnOutOfMemoryError 在OOM时,执行一个脚本。例如:
    -XX:OnOutOfMemoryError=D:/tools/jdk1.7_40/bin/printstack.bat %p,其中printstack.bat里脚本为D:/tools/jdk1.7_40/bin/jstack -F %1 > D:/a.txt。
    当程序OOM时,在D:/a.txt中将会生成线程的dump
    也可以在OOM时,发送邮件,甚至是重启程序
  (3)栈分配参数
  -Xss 通常只有几百K,决定了函数调用的深度,每个线程都有独立的栈空间,局部变量、参数 分配在栈上。
  (4)永久区
  -XX:PermSize  -XX:MaxPermSize
  (5)堆分配参数建议
    根据实际事情调整新生代和幸存代的大小
    官方推荐新生代占堆的3/8
    幸存代占新生代的1/10
    在OOM时,记得Dump出堆,确保可以排查现场问题
4.GC算法
  (1)引用计数算法
  引用计数器的实现很简单,对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就加1,当引用失效时,引用计数器就减1。只要对象A的应用计数器的值为0,则对象A就不可能再被使用,就可以清除了。像python和actionscript用的就是引用计数算法。引用计数有两个问题:i引用和去引用伴随加法和减法,影响性能;ii很难处理循环引用。这个算法java并没有采用。
  (2)标记清除
  标记-清除算法是现代垃圾回收算法的思想基础。标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段。一种可行的实现是,在标记阶段,首先通过根节点,标记所有从根节点开始的可达对象。因此,未被标记的对象就是未被引用的垃圾对象。然后,在清除阶段,清除所有未被标记的对象。
  (3)标记压缩
  标记-压缩算法适合用于存活对象较多的场合,如老年代。它在标记-清除算法的基础上做了一些优化。和标记-清除算法一样,标记-压缩算法也首先需要从跟节点开始,对所有可达对象做一次标记。但之后,它并不简单的清理未标记的对象,而是将所有的存活对象压缩到内存的一端。之后,清理边界外所有的空间。
  (4)复制算法
  与标记-清除算法相比,复制算法是一种相对高效的回收方法。不适用于存活对象较多的场合,如老年代。将原有的内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的存活对象复制到未使用的内存块中,之后,清除正在使用的内存块中的所有对象,交换两个内存的角色,完成垃圾回收。年轻代的from和to两个区(也叫s1和s2)就是复制算法的两个区。
  gc可能引发stop the world(STW)现象。STW是Java中一种全局暂停的现象,这个时候所有Java代码停止运行,native代码可以执行,但不能和JVM交互。原因多半由GC引起,还有dump线程,死锁检查,堆dump也有可能引发STW。危害:i长时间(零点几秒到几十秒,甚至更长)服务停止,没有响应;ii遇到HA系统,可能引起主备切换,严重危害生产环境。
5.分代思想与可触及性
  分代思想:依据对象的存活周期进行分类,短命对象归为新生代,长命对象归为老年代。

  根据不同代的特点,选取合适的收集算法:
    少量对象存活,适合复制算法。
    大量对象存活,适合标记清理或者标记压缩。
  可触及性:
    可触及的:-从根节点可以触及到这个对象。

    可复活的:-旦所有引用被释放,就是可复活状态,因为在finalize()中可能复活该对象。
    不可触及的:-在finalize()后,可能会进入不可触及状态,不可触及的对象不可能复活,可以被回收。
6.GC参数
  (1)串行收集器。最古老,最稳定,

效率高,
可能会产生较长的停顿。
 
    参数:
-XX:+UseSerialGC
      –新生代、老年代使用串行回收
      –新生代复制算法
      –老年代标记-压缩
  
  (2)并行收集器
  
  ParNew收集器
    -XX:+UseParNewGC
    新生代并行,老年代串行
    Serial收集器新生代的并行版本
    复制算法
    多线程,需要多核支持
    -XX:ParallelGCThreads 限制线程数量
  Parallel收集器
    类似ParNew,新生代复制算法,老年代 标记-压缩,更加关注吞吐量。
    -XX:+UseParallelGC  使用Parallel收集器+ 老年代串行。
    -XX:+UseParallelOldGC  使用Parallel收集器+ 并行老年代。
    -XX:MaxGCPauseMills  最大停顿时间,单位毫秒,GC尽力保证回收时间不超过设定值。
    -XX:GCTimeRatio  0-100的取值范围,垃圾收集时间占总时间的比,默认99,即最大允许1%时间做GC。
 
  (3)CMS收集器
    Concurrent Mark Sweep 并发标记清除,这个并发的意思是与用户现场一起执行。
    标记-清除算法
    与标记-压缩相比,并发阶段会降低吞吐量
    老年代收集器(新生代使用ParNew)
    -XX:+UseConcMarkSweepGC
    -XX:+ UseCMSCompactAtFullCollection Full GC后,进行一次整理,整理过程是独占的,会引起停顿时间变长。

    -XX:+CMSFullGCsBeforeCompaction,设置进行几次Full GC后,进行一次碎片整理。
    -XX:ParallelCMSThreads,设定CMS的线程数量。
    CMS运行过程比较复杂,着重实现了标记的过程,可分为
      i.初始标记。根可以直接关联到的对象,速度快。
      ii.并发标记。(和用户线程一起)。主要标记过程,标记全部对象。
      iii.重新标记。由于并发标记时,用户线程依然运行,因此在正式清理前,再做修正。
      iv.并发清除(和用户线程一起)。基于标记结果,直接清理对象
    特点:

      尽可能降低停顿,会影响系统整体吞吐量和性能。比如,在用户线程运行过程中,分一半CPU去做GC,系统性能在GC阶段,反应速度就下降一半。
      清理不彻底,因为在清理阶段,用户线程还在运行,会产生新的垃圾,无法清理。
      因为和用户线程一起运行,不能在空间快满时再清理。-XX:CMSInitiatingOccupancyFraction设置触发GC的阈值,如果不幸内存预留空间不够,就会引起concurrent mode failure。
  (4)几个实例
    以32M堆启动tomcat
  set CATALINA_OPTS=-server -Xloggc:gc.log -XX:+PrintGCDetails -Xmx32M -Xms32M -XX:+HeapDumpOnOutOfMemoryError -XX:+UseSerialGC -XX:PermSize=32M 
  以512M堆启动tomcat
  set CATALINA_OPTS=-Xmx512m -Xms64m -XX:MaxPermSize=32M  -Xloggc:gc.log -XX:+PrintGCDetails -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:ParallelGCThreads=4
  (5)最后汇总一下GC参数:
    -XX:+UseSerialGC:在新生代和老年代使用串行收集器

    -XX:SurvivorRatio:设置eden区大小和survivior区大小的比例
    -XX:NewRatio:新生代和老年代的比
    -XX:+UseParNewGC:在新生代使用并行收集器
    -XX:+UseParallelGC :新生代使用并行回收收集器
    -XX:+UseParallelOldGC:老年代使用并行回收收集器
    -XX:ParallelGCThreads:设置用于垃圾回收的线程数
    -XX:+UseConcMarkSweepGC:新生代使用并行收集器,老年代使用CMS+串行收集器
    -XX:ParallelCMSThreads:设定CMS的线程数量
    -XX:CMSInitiatingOccupancyFraction:设置CMS收集器在老年代空间被使用多少后触发
    -XX:+UseCMSCompactAtFullCollection:设置CMS收集器在完成垃圾收集后是否要进行一次内存碎片的整理
    -XX:CMSFullGCsBeforeCompaction:设定进行多少次CMS垃圾回收后,进行一次内存压缩
    -XX:+CMSClassUnloadingEnabled:允许对类元数据进行回收
    -XX:CMSInitiatingPermOccupancyFraction:当永久区占用率达到这一百分比时,启动CMS回收
    -XX:UseCMSInitiatingOccupancyOnly:表示只在到达阀值的时候,才进行CMS回收
 
这一篇文章先写到这里,下一篇继续^-^
 
  
  
 

jvm基础(1)的更多相关文章

  1. JVM 基础知识

    JVM 基础知识(GC) 2013-12-10 00:16 3190人阅读 评论(1) 收藏 举报 分类: Java(49) 目录(?)[+] 几年前写过一篇关于JVM调优的文章,前段时间拿出来看了看 ...

  2. java 笔记(1)-—— JVM基础,内存数据,内存释放,垃圾回收,即时编译技术JIT,高精度类型

    1.java中5个存放数据的地方: (1).寄存器(Registers):位于CPU内部,是速度最快的存储区,但是数量和容量有限.在java中不能直接操作寄存器. (2).栈(Stack):栈位于通用 ...

  3. JVM基础:深入学习JVM堆与JVM栈

    转自:http://developer.51cto.com/art/201009/227812.htm JVM栈解决程序的运行问题,即程序如何执行,或者说如何处理数据;JVM堆解决的是数据存储的问题, ...

  4. JVM基础知识(1)-JVM内存区域与内存溢出

    JVM基础知识(1)-JVM内存区域与内存溢出 0. 目录 什么是JVM 运行时数据区域 HotSpot虚拟机对象探秘 OutOfMemoryError异常 1. 什么是JVM 1.1. 什么是JVM ...

  5. Jvm基础(2)-Java内存模型

    Jvm基础(2)-Java内存模型 主内存和工作内存 Java内存模型包括主内存和工作内存两个部分:主内存用来存储线程之间的共享变量:而工作内存中存储每个线程的相关变量. 如下图所示: 需要注意的是: ...

  6. 剑指Offer——知识点储备-JVM基础

    剑指Offer--知识点储备-JVM基础 1.java内存与内存溢出 1.1 JVM分为哪些区,每一个区干嘛的?(见java虚拟机38页) (1)程序计数器(线程私有) 当前线程执行字节码的信号指示器 ...

  7. JVM基础系列第15讲:JDK性能监控命令

    查看虚拟机进程:jps 命令 jps 命令可以列出所有的 Java 进程.如果 jps 不加任何参数,可以列出 Java 程序的进程 ID 以及 Main 函数短名称,如下所示. $ jps 6540 ...

  8. JVM基础系列第14讲:JVM参数之GC日志配置

    说到 Java 虚拟机,不得不提的就是 Java 虚拟机的 GC(Garbage Collection)日志.而对于 GC 日志,我们不仅要学会看懂,而且要学会如何设置对应的 GC 日志参数.今天就让 ...

  9. JVM基础系列第13讲:JVM参数之追踪类信息

    我们都知道 JVM 在启动的时候会去加载类信息,那么我们怎么得知他加载了哪些类,又卸载了哪些类呢?我们这一节就来介绍四个 JVM 参数,使用它们我们就可以清晰地知道 JVM 的类加载信息. 为了方便演 ...

  10. JVM基础系列第11讲:JVM参数之堆栈空间配置

    JVM 中最重要的一部分就是堆空间了,基本上大多数的线上 JVM 问题都是因为堆空间造成的 OutOfMemoryError.因此掌握 JVM 关于堆空间的参数配置对于排查线上问题非常重要. tips ...

随机推荐

  1. Event based Collections

    https://sourceforge.net/p/happy-guys/wiki/Event%20based%20Collections/

  2. HDU——1465不容易系列之一(错排公式)

    不容易系列之一 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Su ...

  3. Miracast HDCP 等知识

    Miracast 通讯架构中关于视频数据处理流程的部分.整个视频数据处理及传输的流程,大致上分为几个阶段,一开始将撷取到系统的画面及声音进行压缩,而压缩后的影音数据再转为基本封包串流(Packetiz ...

  4. 文本生成器(bzoj 1030)

    Description JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是 ...

  5. 2017.8.1 Noip2018模拟测试赛(十七)

    日期: 八月第一天  总分: 300分  难度: 提高 ~ 省选    得分: 100分(不应该啊!) 题目目录: T1:战争调度 T2:选数 T3:由乃的OJ 赛后心得: MMP,首先第一题花了大概 ...

  6. [转]使用ProxyFactoryBean创建AOP代理

    http://doc.javanb.com/spring-framework-reference-zh-2-0-5/ 7.5. 使用ProxyFactoryBean创建AOP代理 - Spring F ...

  7. hdu 5459(递推好题)

    Jesus Is Here Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)To ...

  8. MVC中使用ajax传递json数组

    解决方法 去www.json.org下载JSON2.js再调用JSON.stringify(JSONData)将JSON对象转化为JSON串. var people = [{ "UserNa ...

  9. AC日记——图灵机游戏 codevs 2292

    2292 图灵机游戏  时间限制: 1 s  空间限制: 64000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description [Shadow 1]第二题 ...

  10. Hibernate游记——装备篇《二》(基础配置示例)

    <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hi ...