其他分享
首页 > 其他分享> > jvm进阶

jvm进阶

作者:互联网

1.随着JIT编译器的发展,在编译期间,如果JIT经过逃逸分析,发现有些对象没有逃逸出方法,那么有可能堆内存分配会被优化成栈内存分配。但是这并不是绝对的。
2.JVM在内存新生代Eden Space中开辟了一小块区域,由线程私有,称作TLAB(Thread-local allocation buffer),默认设定为占用Eden Space的1%。在Java程序中很多对象都是小对象且用过即丢,它们不存在线程共享也适合被快速GC,所以对于小对象通常JVM会优先分配在TLAB上,并且TLAB上的分配由于是线程私有所以没有锁开销。因此在实践中分配多个小对象的效率通常比分配一个大对象的效率要高。
虚拟机是否使用TLAB,可以通过-XX:+/-UseTLAB参数来设定;通常默认的TLAB区域大小是Eden区域的1%,当然也可以手工进行调整,对应的JVM参数是-XX:TLABWasteTargetPercent。

 

 

 

什么情况下会发生栈内存溢出?
是否有递归调用
是否有大量循环或死循环
全局变量是否过多
数组、List、map数据是否过大
使用DDMS工具进行查找大概出现栈溢出的位置
什么情况下会发生堆内存溢出?
是否App中的类中和引用变量过多使用了Static修饰
是否App中使用了大量的递归或无限递归(递归中用到了大量的建新的对象)
是否App中使用了大量循环或死循环(循环中用到了大量的新建的对象)
检查App中是否使用了向数据库查询所有记录的方法。即一次性全部查询的方法,如果数据量超过一定数量,就可能会造成内存溢出。所以在查询时应采用“分页查询”。
检查是否有数组,List,Map中存放的是对象的引用而不是对象,因为这些引用会让对应的对象不能被释放。会大量存储在内存中。
检查是否使用了“非字面量字符串进行+”的操作。因为String类的内容是不可变的,每次运行"+"就会产生新的对象,如果过多会造成新String对象过多,从而导致JVM没有及时回收而出现内存溢出。

线程之间如何通信

https://zhuanlan.zhihu.com/p/51613784

 

8 种基本操作,如下图:

 

内存交互基本操作的 3 个特性

原子性(Atomicity)

可见性(Visibility)

有序性(Ordering)

2、happens-before 关系

介绍系列规则之前,首先了解一下 happens-before 关系:用于描述下 2 个操作的内存可见性。如果操作 A happens-before 操作 B,那么 A 的结果对 B 可见。

happens-before 关系的分析需要分为单线程和多线程的情况:

为了方便程序开发,Java 内存模型实现了下述支持 happens-before 关系的操作:

标签:happens,进阶,线程,内存,jvm,操作,变量,before
来源: https://www.cnblogs.com/sxsheng/p/15415641.html