理解JVM(2) 栈内存,方法区,堆内存
来源:互联网 发布:jni返回byte数组传递 编辑:程序博客网 时间:2024/05/14 06:55
堆,方法区,栈的关系
分配最大堆内存-Xmx32m
class SimpleHeap(val id: Int){ fun show() = println("My id is $id")}fun main(args: Array<String>) { val s1 = SimpleHeap(1) val s2 = SimpleHeap(2) s1.show() s2.show()}
方法区内保存类的基本信息,包括方法的实现。方法区里面的信息很少清除
Java堆内保存着s1,s2的实例
Java栈内保存着s1和s2的方法show()的局部变量
栈的溢出测试
栈帧包括:局部变量表(原生类型或引用类型的对象引用),操作数栈(类似于寄存器结构,用于计算),帧数据区(常量池指针和异常处理表)
分配最大栈内存-Xss228K
var count = 0class SimpleHeap{ fun show(){ count++ val KB = ByteArray(1024*10) KB.set(count, count.toByte()); show() }}
上面代码,我以为是保存了10K的局部变量,后来发现数组还是放在堆内存里面的,栈中只保存一个引用。所以还是能递归3000次吧
var count = 0class SimpleHeap{ fun show(){ count++ val a = 1L val b = 2L val c = 3L val d = 4L val e = 5L val f = 6L val g = 7L val h = 8L val i = 9L val j = 10L show() }}
一共调用670次,每次调用会使用350个字节,然后局部变量会保存80字节的long型局部变量
堆内存回收分析
class SimpleHeap{ fun gc1(){ val MB = ByteArray(1024*1024*6) System.gc() //不会马上回收内存 } fun gc2(){ var MB: ByteArray? = ByteArray(1024*1024*6) MB = null System.gc() } fun gc3(){ { var MB = ByteArray(1024*1024*6) } System.gc() } fun gc4(){ { var MB = ByteArray(1024*1024*6) } val c = 10 System.gc() } fun gc5(){ gc1() System.gc() }}
gc1()
可以看到没有回收内存。
gc2()
可以发现,又多分配了6MB,然后马上回收,这次一次性回收了12MB,因为gc1()的6MB也给回收了。
gc3(),gc4(),gc5()
gc3()gc4()不能为什么,根本没有分配内存,说不定给Kotlin编译器给优化了。
gc5()在gc1()退出作用域后,直接回收掉了6MB
栈上分配内存
对于那些线程私有的对象(指不会被其他线程访问到的对象),可以打散分配在栈上,而不是分配在堆上。在函数调用后自行下载,而不用垃圾收集器。
实现的技术是进行逃逸分析-XX:+DoEscapeAnalysis
/*-server -Xmx10m -Xms10m -XX:+PrintGC -XX:+DoEscapeAnalysis -XX:-UseTLAB -XX:+EliminateAllocations*/class OnStackTest{ class User(val id:Int = 0, val name:String = ""){ } companion object { fun alloc(){ val u = User(5,"owen") } }}fun main(args: Array<String>) { val b = System.currentTimeMillis() for (i in 0..1000000000){ OnStackTest.alloc() } val c = System.currentTimeMillis() println(c - b)}
要调用100000000次,按理说会频繁调用GC,但栈上分配技术显示, 咳咳,按理说是看不到GC日志
[GC (Allocation Failure) 2047K->544K(9728K), 0.0032233 secs][GC (Allocation Failure) 2592K->472K(11776K), 0.0080457 secs]60
方法区
保存系统的类信息,比如类的字段,方法,常量池。
Java1.6,1.7可以理解为永久代(Perm),设置参数为-XX:PermSize=5m,-XX:MaxPermSize=5m
Java1.8中变成了元数据区,使用-XX:MaxMetaspaceSize指定,这是一块堆外的直接内存,如果不指定大小,虚拟机会耗尽所有系统的可用内存
阅读全文
0 0
- 理解JVM(2) 栈内存,方法区,堆内存
- JVM内存初学 堆、栈、方法区
- JVM 内存 (堆(heap)、栈(stack)和方法区(method) )
- JVM 内存 (堆(heap)、栈(stack)和方法区(method) )
- JVM 内存 (堆(heap)、栈(stack)和方法区(method) )
- java堆内存、栈内存、方法区
- JVM内存管理,堆、栈
- jvm 堆内存 栈内存 大小设置
- jvm 堆内存 栈内存 大小设置
- 【JVM】堆内存与栈内存详解
- jvm 内存划分 栈区 堆区 方法区
- jvm 内存划分 栈区 堆区 方法区
- jvm内存分析 计数器 堆 栈 本地方法栈 方法区
- JVM内存管理-----堆内存
- jvm 堆内存 栈内存 大小设置 查看堆大小
- 增加JVM堆内存
- Jvm堆内存管理
- jvm 堆内存分配
- the first day in csdn
- Animation与Animator(Animation调用动画报空问题)
- 一些自己收集到的教程免费发布出来
- springcloud微服务实战:Eureka+Zuul+Ribbon+Hystrix+SpringConfig
- taskctl条件控制策略中时间窗口注意事项
- 理解JVM(2) 栈内存,方法区,堆内存
- Codeforces Round #434 (Div. 2)
- 《深入理解mybatis原理》 MyBatis事务管理机制 http://blog.csdn.net/luanlouis/article/details/37992171
- python 指定运行版本,python 版本
- sklearn 学习(一)数据集介绍
- VMware tools的安装和使用
- HTTP请求结构
- Entity层简介及配置
- pycharm同时使用python2.7和python3.5设置方法