`
hpgary
  • 浏览: 78691 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Java内存模型-JMM 和 jvm优化

    博客分类:
  • Java
JMM 
阅读更多

一、Java内存模型简介

Java内存模型是Java里面高级技术也是很难理解的部分,希望能通过这篇文章让大家对JMM不在那么陌生,当很了解Java内存模型后Java多线程也就就会变得容易许多。

 

二、堆、栈和方法区存储了些什么

堆区:

1、存储的全部都是对象,每个对象包含一个与之对应的class的信息。

2、jvm只有一个堆区被所有的线程共享,堆中不存放基本类型和对象的引用

栈区:

1、每个线程包括一个栈区,栈中只保存基本数据类型的对象和自定义对象的引用(不是对象)

2、每个栈中的数据(基本数据类型和对象引用)都是私有的,其他栈没有权限访问

3、栈分为三个区:基本数据类型变量区、执行环境上下文、操作指令区(存放操作指令)

方法区:

1、又叫静态区,跟堆一样,被所有线程共享,包含所有的class对象和静态变量

2、方法区包含的都是整个程序中永远唯一的元素如,static 对象

内存模型图如下:

 



 

 

三、一个类在堆和栈区域如何存储

按照第二点,可以得出一个Employee类在堆、栈、方法区域如何存储的。

  


 
 如图可以看出,e2和e3在heap区域指向同一个地址,如图所示就是一个类在对喝栈的存储,方法区域存储class信息和静态变量

 

四、CPU乱序

多线程使用使用和赋值同一个对象时,会导致CPU乱序例如下列代码:

 
  启动10个线程,对静态变量i个自增一万次,每次运行结果都不一样。
首先分析下i++: i++在cpu计算过程中分三步,第一个 获取i的值, 第二步 计算i+1、 第三步赋值 i=新值。
然后分析下CPU乱序:cpu每次都要把计算结果写回到主存中,CPU读写主存相当于一个很慢的IO,需要大量的时间,这时候CPU会将其他运行速度比较快的指定优先运行。
因为cpu乱序和多步计算导致出现结果和预期不一致的问题
为了避免此类问题发送,Java引进了原子类操作类:AtomicInteger,改进后,不在出现循环10万次最终结果不是10万了。
 
 五、Unsafe 原子操作对象
获取Unsafe对象实例:
Unsafe unsafe = (Unsafe) FieldUtils.readStaticField(Unsafe.class, "theUnsafe", true);
 Unsafe直接操作数组:
// 获取数组在内存中的位置
long byteBaseOffset = unsafe.arrayBaseOffset(byte[].class);
//定义一个byte数组
byte[] bytes = new byte[10];
//给数组每个元素设置值
for (int x = 0; x < bytes.length; x++) {
	unsafe.putByte(bytes, byteBaseOffset + x, (byte) (x+1) );
}
// 获取数组某个元素的值
unsafe.getByte(arg0.bytes, byteBaseOffset + 7 ) ;   
 
六、JVM堆、栈、内存参数设置
-Xms 初始堆大小

-Xmx 最大堆大小

-Xmn 设置年轻代大小

-XX:PermSize 设置持久代(perm gen)初始值

-XX:MaxPermSize 设置持久代最大值

-Xss 每个线程的堆栈大小

-XX:NewRatio 年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。XX:NewRatio=4 表示年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5

-XX:SurvivorRatio  Eden区与Survivor区的大小比值。设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10

-XX:MaxTenuringThreshold 垃圾最大年龄

 

更多参数,待更新。。。

 

七、jvm 内存监控

jstat -gcutil 29530 100 10

S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   

0.00  99.06  37.01   2.41  96.15  93.00      7    0.368     2    0.426    0.794

0.00  99.06  37.01   2.41  96.15  93.00      7    0.368     2    0.426    0.794

0.00  99.06  37.01   2.41  96.15  93.00      7    0.368     2    0.426    0.794

0.00  99.06  37.01   2.41  96.15  93.00      7    0.368     2    0.426    0.794

0.00  99.06  37.01   2.41  96.15  93.00      7    0.368     2    0.426    0.794

 

1、S0、S1:Survivor 0/1 使用量(Used) 

2、EC、EU:Eden区容量和使用量

3、OC、OU:年老代容量和使用量

4、PC、PU:永久代容量和使用量

5、YGC、YGT:年轻代GC次数和GC耗时

6、FGC、FGCT:Full GC次数和Full GC耗时

7、GCT:GC总耗时

 

八、持久代被占满

异常:java.lang.OutOfMemoryError: PermGen space

说明: Perm空间被占满。无法为新的class分配存储空间而引发的异常。这个异常以前是没有的,但是在Java反射大量使用的今天这个异常比较常见了。主要原因就是大量动态反射生成的类不断被加载,最终导致Perm区被占满。 更可怕的是,不同的classLoader即便使用了相同的类,但是都会对其进行加载,相当于同一个东西,如果有N个classLoader那么他将会被加载N次。因此,某些情况下,这个问题基本视为无解。当然,存在大量classLoader和大量反射类的情况其实也不多。

解决:

    1. -XX:MaxPermSize=1G

    2. 换用JDK。比如JRocket。

 

九、堆栈溢出

异常:java.lang.StackOverflowError

说明:这个就不多说了,一般就是递归没返回,或者循环调用造成

 

十、线程堆栈满

异常:Fatal: Stack size too small

说明:java中一个线程的空间大小是有限制的。JDK5.0以后这个值是1M。与这个线程相关的数据将会保存在其中。但是当线程空间满了以后,将会出现上面异常。

解决:增加线程栈大小。-Xss512。但这个配置无法解决根本问题,还要看代码部分是否有造成泄漏的部分。

 

十一、异常:java.lang.OutOfMemoryError: unable to create new native thread

说明:

    这个异常是由于操作系统没有足够的资源来产生这个线程造成的。系统创建线程时,除了要在Java堆中分配内存外,操作系统本身也需要分配资源来创建线程。因此,当线程数量大到一定程度以后,堆中或许还有空间,但是操作系统分配不出资源来了,就出现这个异常了。

分配给Java虚拟机的内存愈多,系统剩余的资源就越少,因此,当系统内存固定时,分配给Java虚拟机的内存越多,那么,系统总共能够产生的线程也就越少,两者成反比的关系。同时,可以通过修改-Xss来减少分配给单个线程的空间,也可以增加系统总共内生产的线程数。

解决:

    1. 重新设计系统减少线程数量。

    2. 线程数量不能减少的情况下,通过-Xss减小单个线程大小。以便能生产更多的线程。

 

 
  • 大小: 38.8 KB
  • 大小: 27.5 KB
  • 大小: 42 KB
  • 大小: 183.9 KB
分享到:
评论

相关推荐

    三问JMM--有关JVM内存模型的PPT

    有关JVM内存模型的概述,用于对JVM的整体把握从而针对性的学习

    jMM+JVM-GC COLLECTOR+调优.pptx

    一个PPT包含 java内存模型,class运行机制。 java jvm垃圾回收算法 java jvm gc常见垃圾回收算法分析 java jvm调优

    java内存模型JMM(Java Memory Model)1

    由于JVM运行程序的实体是线程,而每个线程创建时JVM都会为其创建一个工作内存(有些地方称为栈空间),工作内存是每个线程的私有数据区域,而Java内存模型中规定

    深入理解Java内存模型(经典).rar

    深入理解Java内存模型

    笔记-9、JMM和底层实现原理1

    目录 并发编程领域的关键问题 1 现代计算机物理上的内存模型 2 Java内存模型(JMM) 2 JVM对Java内存模型的实现 3 Java内存模型带来的问题

    jvm详细内存模型图1

    查看《深入理解Java虚拟机》后,自己简单总结的jvm相关的简单模型图。

    Java内存模型JMM详解

    主要介绍了Java内存模型JMM详解,涉及volatile和监视器锁,final字段,内存屏障等相关内容,具有一定参考价值,需要的朋友可以了解下。

    深入理解Java内存模型

    深入理解Java内存模型,写的比较一栋,对于理解java内存有参考意义

    Java内存模型JMM浅析

    并发编程有多种风格,除了CSP(通信顺序进程)、Actor等模型外,大家最熟悉的应该是基于线程和锁的共享内存模型了。在多线程编程中,需要注意三类并发问题:1.原子性2.可见性3.重排序原子性涉及到,一个线程执行一个...

    jvm-readings:JVM读数

    JVM阅读工作正在进行中对于理解... 安全点 本征 Java内存模型JMM基础知识:访问原子性,单词撕裂,顺序一致性,同步顺序,SO-PO / SO一致性,按顺序同步,发生之前,顺序一致性-数据竞速免费,“蟑螂汽车旅馆”,凭空而

    面试必问:Java 内存模型的3个特性

    Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能得到一致效果的「机制及规范」。 JMM与Java内存区域是两个...

    java8源码-concurrency:java并发总结

    Java内存模型 1.8 可重入 1.9 偏向锁、轻量级锁、重量级锁 1.10 锁的公平性 1.11 线程组 2 多线程基本实现 2.1 多线程实现 Interface Runnable Callable Future ExecutorService Class Thread FutureTask FutureTask...

    java内核源码-JavaCompass:「Java指南针」为你学习Java指明方向。内容涵盖互联网Java工程师所需要掌握的核心知识,涉及J

    java内核源码 Java指南针 基础核心 基础知识 反射 泛型 动态代理 JDK8新特性 集合容器 ...JMM内存模型 并发同步处理 并发包之tools工具 并发包之atomic原子操作 阻塞队列BlockingQueue详解 并发Map、Lis

    Potato:阅读适用于Android采访的他妈的源代码-android source code

    [目录] 阅读面试的源代码计划 本项目逐步面试准备过程的...:JVM内存结构,Java内存模型(JMM),Java对象模型 :HashMap源码分析 :Java线程和并发知识总结 : 和并发结合总结 :java各种锁 安卓 交互:Android nati

    [Java] volatile 详详解!

    JMM:JAVA内存模型(java memory model) 是一种抽象概念,并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(实例字段,静态字段和构成数组对象的元素)的访问方式。 JMM关于同步的规定 ...

    线程安全之可见性揭秘-《云课堂》

    JVM运行时数据区和JMM(java内存模型)有什么区别? 1. JVM运行时数据区 是 由 《==Java虚拟机规范==》定义的 理解:不同的JVM厂商都必须 遵循 《==Java虚拟机规范==》进行开发 2. JMM是由 《java语言规范》定义的 ...

    Wws_Android_Interview

    JMM(Java内存结构模型) Android基础(三天1.25-27,参考第一行代码及官方文档) 四大组件 活动的作用,生命周期(典型场景下生命周期的调用顺序),启动模式 服务的作用,两种启动模式(startService和...

    leetcode下载-Note:我的笔记

    volatile理解,JMM中主存和工作内存到底是啥?和JVM各个部分怎么个对应关系? 序列化,Serializable在序列化时使用了反射,从而导致GC的频繁调用。 可见性,原子性,有序性 可见性volatile,一个线程的修改对另外一...

    国内面试leetcode-Android-Interview:Android-面试

    4、Jvm虚拟机:如执行过程、JMM模型、Java Gc回收原理、类加载器等。 5、数据结构和算法:LeetCode+剑指Offer。 6、Android基础:启动模式、动画、自定义View等。 7、Android进阶:进程间通信、Binder、AIDL、AMS/...

Global site tag (gtag.js) - Google Analytics