(转载)固然Java屏蔽了一下内存细节,但是有时候,了解一下这些常识还是有好处的,特别是一些口试,总是盯着这些玩意不放手。

JVM启动以后,会分配两类内存区域,一类用于开发职员使用,比如保存一些变量,对象等,一类JVM自己使用,比如存放一些class类和描述。

1,第一类内存区域又可以分为栈(stack)、堆(heap),还有一些静态存储区域,这部分的内存在JVM启动的时候,可以用参数进行配置:

-Xms 初始堆大小,这个值不能太小,其初始空间(即-Xms)是物理内存的1/64,这个值不能太小,比如 设置了-Xms1m,运行可能会出现

Error occurred during initialization of VM

Too small initial heap for new size specified

-Xmx 堆大小上限,最大空间(-Xmx)是物理内存的1/4,假如程序中分配的内存超过了这个限制,那么会出现

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

代码为:

byte[] b = new byte[100000000];

-Xss 线程栈大小,一般不用设置,JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。有时候会发现一下异常,

Exception in thread "main" java.lang.StackOverflowError

原因一般是:

public static int callMyself(){

return callMyself();

}

方法的递回或者死循环,导致栈空间不够用了。

栈和堆到底存些什么,很多地方都有讲到,这里参考下《Think in java》的,栈里存放对象引用、基本类型的变量等,而堆里面存放对象和数组。方法的执行是在栈上进行的,这一点可以通过异常的时候,经常会默认打印

e.printStackTrace();

栈信息得知。

Runtime类有几个函数,我们可以简单的通过这几个函数,看看JVM中的一些内存信息。

maxMemory()这个方法返回的是java虚拟机(这个进程)能构从操纵系统那里挖到的最大的内存,以字节为单位,假如在运行java程序的时 候,没有添加-Xmx参数,那么就是64兆,也就是说maxMemory()返回的大约是64*1024*1024字节,这是java虚拟机默认情况下能 从操纵系统那里挖到的最大的内存。假如添加了-Xmx参数,将以这个参数后面的值为准,例如java -cp ClassPath -Xmx512m ClassName,那么最大内存就是512*1024*0124字节。

totalMemory()这个方法返回的是java虚拟机现在已经从操纵系统那里挖过来的内存大小,也就是java虚拟机这个进程当时所占用的所有 内存。假如在运行java的时候没有添加-Xms参数,那么,在java程序运行的过程的,内存总是慢慢的从操纵系统那里挖的,基本上是用多少挖多少,直 挖到maxMemory()为止,所以totalMemory()是慢慢增大的。假如用了-Xms参数,程序在启动的时候就会无条件的从操纵系统中挖- Xms后面定义的内存数,然后在这些内存用的差未几的时候,再往挖。

freeMemory()是什么呢,刚才讲到假如在运行java的时候没有添加-Xms参数,那么,在java程序运行的过程的,内存总是慢慢的从操 作系统那里挖的,基本上是用多少挖多少,但是java虚拟机100%的情况下是会稍微多挖一点的,这些挖过来而又没有用上的内存,实际上就是 freeMemory(),所以freeMemory()的值一般情况下都是很小的,但是假如你在运行java程序的时候使用了-Xms,这个时候由于程 序在启动的时候就会无条件的从操纵系统中挖-Xms后面定义的内存数,这个时候,挖过来的内存可能大部分没用上,所以这个时候freeMemory()可 能会有些大。

下面我们来看看例子:

Runtime rt = Runtime.getRuntime();

info("Max   memory: " + rt.maxMemory());

long fisrt = rt.freeMemory();

info("Total memory: " + rt.totalMemory());

info("Free memory: " + fisrt);

int size = 10000;

byte[] b = new byte[size];

long bL = rt.freeMemory();

info("Free memory: " + bL);

info("byte allocate Cost memory: " + (fisrt - bL) + ", Array size :" + size);

运行参数为 -Xms8m -Xmx32m (太大了可能看不出来),运行结果为:

2011-02-22 10:28:01: Max   memory: 33357824

2011-02-22 10:28:01: Total memory: 8323072

2011-02-22 10:28:01: Free memory: 7791752

2011-02-22 10:28:01: Free memory: 7781736

2011-02-22 10:28:01: byte allocate Cost memory: 10016, Array size :10000

33357824 <> 32*1025*1024(大约即是)

8323072 <> 8×1024×1024

最后看看10000长度的byte数组,分配了多少内存,大约为10016,这说明除了10000个大小为1字节的byte以外,还有16个字节其他的玩意。

将byte换成int(4字节):

2011-02-22 10:35:21: int allocate Cost memory: 40016, Array size :10000

与byte相同,也是4*10000+16

将byte换成long(8字节):

2011-02-22 10:32:47: long allocate Cost memory: 80016, Array size :10000

与byte相同,也是8*10000+16

再看看String数组:

2011-02-22 10:34:40: String allocate Cost memory: 40016, Array size :10000

String作为一个对象,分配的内存大小与int相同,说明了这台机器是32(4*8)位的

最后看看Object对象,

2011-02-22 10:37:02: Object allocate Cost memory: 40016, Array size :10000

与String一样。

2,第二类内存,我了解的主要是PermGen space,全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,SUN的JDK在GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以假如你的应用中有很CLASS的话,就很可能出现PermGen space错误。

原来SUN 的JVM把内存分了不同的区,其中一个就是permenter区用来存放用得非常多的类和类描述。本来SUN设计的时候以为这个区域在JVM启动的时候就 固定了,但他没有想到现在动态会用得这么广泛。而且这个区域有特殊的垃圾收回机制,现在的题目是动态加载类到这个区域后,gc根本没办法回收!

JAVA 内存的那些事的更多相关文章

  1. 聊聊高并发(三十四)Java内存模型那些事(二)理解CPU快速缓存的工作原理

    在上一篇聊聊高并发(三十三)从一致性(Consistency)的角度理解Java内存模型 我们说了Java内存模型是一个语言级别的内存模型抽象.它屏蔽了底层硬件实现内存一致性需求的差异,提供了对上层的 ...

  2. java内存的那些事

    在Java中,内存的管理分为以下几个部分: Heap:堆区域,存放对象实例,凡是New出来的东西都存放在此. Stack:栈区域,存放基本数据类型.常量.局部变量.对象的引用地址 Data Segme ...

  3. Java内存模型之总结

    经过四篇博客阐述,我相信各位对Java内存模型有了最基本认识了,下面LZ就做一个比较简单的总结. 总结 JMM规定了线程的工作内存和主内存的交互关系,以及线程之间的可见性和程序的执行顺序.一方面,要为 ...

  4. 程序计数器(关于java虚拟机内存的那些事)

    <深入理解java虚拟机> 读书感悟 作者:淮左白衣 --------------写于2018年4月9日17:44:48 关于java虚拟机内存的那些事之程序计数器 关于java虚拟机内存 ...

  5. Java内存模型(JMM)那些事

    本文是库存文章,去年年底学习了慕课网的并发编程课程,今年年初看完了<深入理解Java虚拟机>这本书,但是很多内容忘得差不多了,打算写写博客回忆一下那些忘在脑后的知识点. 温故而知新 更多J ...

  6. Java 内存管理

    java 内存管理机制 JAVA 内存管理总结 java 是如何管理内存的 Java 的内存管理就是对象的分配和释放问题.(两部分) 分配 :内存的分配是由程序完成的,程序员需要通过关键字 new 为 ...

  7. Java 内存区域和GC机制分析

    目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...

  8. java内存管理机制

    JAVA 内存管理总结 1. java是如何管理内存的 Java的内存管理就是对象的分配和释放问题.(两部分) 分配 :内存的分配是由程序完成的,程序员需要通过关键字new 为每个对象申请内存空间 ( ...

  9. Java 内存区域和GC机制

    目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...

随机推荐

  1. Nginx源码安装配置

    Nginx web服务器简介 Nginx ("engine x") 是一个高性能HTTP 和 反向代理 服务器.IMAP.POP3.SMTP 服务器. Nginx 是由 Igor ...

  2. facenet pyhton3.5 训练 train_softmax.py 时报错AttributeError: 'dict' object has no attribute 'iteritems'

    报错原因:在进行facenet进行train_softmax.py训练时,在一轮训练结束进行验证时,报错AttributeError: 'dict' object has no attribute ' ...

  3. 【51nod1672】区间交

    题目大意:给定一个长度为 N 的序列,以及 M 个区间,现从中选出 K 个区间,使得这些区间的交集区间的点权和最大,求最大值是多少. 题解: 发现直接选 K 个区间不可做,考虑从答案入手.设答案区间为 ...

  4. 京东POP店铺使用京东物流切仓操作方法

    首先进入京东物流工作台:https://wl.jdwl.com/ 在运营管理中,点击店铺商品 然后看截图操作

  5. C# AVI Image 转换

    AVI视频库 http://download.csdn.net/download/qc_id_01/9970151 Avi视频文件的编码有很多,这个库只支持部分Avi文件,有些Avi文件不支持,具体哪 ...

  6. 【GDSOI2019】滑稽二乘法【数据结构】【LCT】

    Description 点数<=100000,操作数<=200000 Solution 经典的LCT维护子树路径信息的问题. 具体来说,我们对于每一个节点,它在splay上的子树对应了原树 ...

  7. luoguP2285 [HNOI2004]打鼹鼠 x

    P2285 [HNOI2004]打鼹鼠 题目描述 鼹鼠是一种很喜欢挖洞的动物,但每过一定的时间,它还是喜欢把头探出到地面上来透透气的.根据这个特点阿牛编写了一个打鼹鼠的游戏:在一个n*n的网格中,在某 ...

  8. TensorFlow使用记录 (一): 基本概念

    基本使用 使用graph来表示计算任务 在被称之为Session的上下文中执行graph 使用tensor表示数据 通过Variable维护状态 使用feed和fetch可以为任意的操作(op)赋值或 ...

  9. mongodb php增删改查基本操作

    $mongo = new Mongo(); $db = $mongo->selectDB('test'); $collection = $db->selectCollection('foo ...

  10. Linux命令-文件传输

    Linux命令-文件传输 Linux lprm命令 Linux lprm命令用于将一个工作由打印机贮列中移除 尚未完成的打印机工作会被放在打印机贮列之中,这个命令可用来将常未送到打印机的工作取消.由于 ...