堆,方法区,栈的关系

分配最大堆内存-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 = 0
class SimpleHeap{
fun show(){
count++
val KB = ByteArray(1024*10)
KB.set(count, count.toByte());
show()
}
}

上面代码,我以为是保存了10K的局部变量,后来发现数组还是放在堆内存里面的,栈中只保存一个引用。所以还是能递归3000次吧

var count = 0
class 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指定,这是一块堆外的直接内存,如果不指定大小,虚拟机会耗尽所有系统的可用内存

理解JVM2 栈内存,方法区,堆内存的更多相关文章

  1. JVM内存结构之堆、栈、方法区以及直接内存、堆和栈区别

    JVM内存结构之堆.栈.方法区以及直接内存.堆和栈区别 一.  理解JVM中堆与栈以及方法区 堆(heap):FIFO(队列优先,先进先出):二级缓存:*JVM中只有一个堆区被所有线程所共享:对象和数 ...

  2. 堆、栈、方法区、静态代码块---Java

    java 堆.栈.方法区 堆区: 1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的目的是得到操作指令) 2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基 ...

  3. java内存管理(堆、栈、方法区)

    java内存管理 简介 首先我们要了解我们为什么要学习java虚拟机的内存管理,不是java的gc垃圾回收机制都帮我们释放了内存了吗?但是在写程序的过程中却也往往因为不懂内存管理而造成了一些不容易察觉 ...

  4. [二]Java虚拟机 jvm内存结构 运行时数据内存 class文件与jvm内存结构的映射 jvm数据类型 虚拟机栈 方法区 堆 含义

    前言简介 class文件是源代码经过编译后的一种平台中立的格式 里面包含了虚拟机运行所需要的所有信息,相当于 JVM的机器语言 JVM全称是Java Virtual Machine  ,既然是虚拟机, ...

  5. JVM内存的堆、栈和方法区

    JVM的内存分为堆.栈.方法区和程序计数器4个区域 存储内容:基本类型,对象引用,对象本身,class,常量,static变量 堆: 拥有者:所有线程 内容:对象本身,不存放基本类型和对象引用 垃圾回 ...

  6. 简单了解下java中的堆、栈和方法区。

    堆.栈.方法区 1,首先了解下java中的数据类型. ①java中的八大基本数据类型:boolean, char , byte, short, int, long , float , double. ...

  7. java中的堆、栈、方法区等比较

    • 堆.栈.方法区 1. java中的栈(stack)和堆(heap)是java在内存(ram)中存放数据的地方 2. 堆区 存储的全部是对象,每个对象都包含一个与之对应的class的信息.(clas ...

  8. 【转载】java项目中经常碰到的内存溢出问题: java.lang.OutOfMemoryError: PermGen space, 堆内存和非堆内存,写的很好,理解很方便

    Tomcat Xms Xmx PermSize MaxPermSize 区别 及 java.lang.OutOfMemoryError: PermGen space 解决 解决方案 在 catalin ...

  9. Java虚拟机的内存组成以及堆内存介绍

    一.java内存组成介绍:堆(Heap)和非堆(Non-heap)内存 按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在 Java 虚拟机启 ...

  10. 干货:JVM 堆内存和非堆内存

    堆和非堆内存 按照官方的说法:"Java 虚拟机具有一个堆(Heap),堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在 Java 虚拟机启动时创建的."" ...

随机推荐

  1. uva-10391-枚举

    题意:对于输入的字符串,判断是否存在一个单词a=b+c 俩种方法,枚举每一个单词进行拼接,复杂度是n*n 枚举每一个单词,对单词进行substr,判断substr出来的是不在map里面 #includ ...

  2. uva-10422-骑士-搜索题

    题意: 给你一个5X5的图,棋盘上骑士的走法自己去百度,问能不能在10步内走到目标图, 解题思路: 从目标图开始往前走10步,保存所有能走到的图,然后输入,查找是否存在这个图,存在就是可以走到,不存在 ...

  3. Tomcat 之session 持久化2

    通过前文 Tomcat 之session 持久化1 ,我们已经大概了解了这么个机制.但是我没能详细展开其底层的原理. 这篇文章,我想稍微深入一点点,再继续聊一聊其底层. Tomcat 之session ...

  4. 监控msyql 连接数 及 各用户连接数

    #!/bin/bash while true do date +%Y%m%d-%H:%M:%S mysql -uroot -p'xxx' -e "select count(1) from i ...

  5. java环境变量配置方法

    原创文章,转载请注明出处. 这是本人2011-9-4记录的,现在把它放在博客上. windows xp下配置JDK环境变量: 1.安装JDK,安装过程中可以自定义安装目录等信息,例如我们选择安装目录为 ...

  6. golang web框架 beego

    尝试了下,在go环境ready的情况下,花了2分钟完成了beego安装.项目生成和启动,效率还是不错的 1.安装: go get github.com/astaxie/beego go get git ...

  7. 机器学习入门-数值特征-连续数据离散化(进行分段标记处理) 1.hist(Dataframe格式直接画直方图)

    函数说明: 1. .hist 对于Dataframe格式的数据,我们可以使用.hist直接画出直方图 对于一些像年龄和工资一样的连续数据,我们可以对其进行分段标记处理,使得这些连续的数据变成离散化 就 ...

  8. JEECG 新手常见问题大全,入门必读

    大家还有什么问题,请跟帖,谢谢支持..  JEECG常见问题大全 原文地址:http://t.cn/RvYsEF61. jeecg数据库脚本问题   注意:jeecg3.5.2之前版本,不需要数据库脚 ...

  9. AS2 笔记 1——attachMovie 添加库影片

    this["container"].attachMovie("useLoad", "useLoadMc", this.getNextHigh ...

  10. JSdom操作内容,样式,属性

    <p> JavaScript 能够直接写入 HTML 输出流中: </p> <script> document.write("<h1>This ...