内存

java内存分配和String类型的深度解析

拟墨画扇 提交于 2019-12-01 18:25:34
一、引题 在java语言的所有数据类型中,String类型是比较特殊的一种类型,同时也是面试的时候经常被问到的一个知识点,本文结合java内存分配深度分析关于String的许多令人迷惑的问题。下面是本文将要涉及到的一些问题,如果读者对这些问题都了如指掌,则可忽略此文。 1、java内存具体指哪块内存?这块内存区域为什么要进行划分?是如何划分的?划分之后每块区域的作用是什么?如何设置各个区域的大小? 2、String类型在执行连接操作时,效率为什么会比StringBuffer或者StringBuilder低?StringBuffer和StringBuilder有什么联系和区别? 3、java中常量是指什么?String s = "s" 和 String s = new String("s") 有什么不一样? 本文经多方资料的收集整理和归纳,最终撰写成文,如果有错误之处,请多多指教! 二、java内存分配 1、JVM简介 Java 虚拟机 (Java Virtual Machine 简称JVM)是运行所有Java程序的抽象计算机,是 Java语言 的运行环境,它是Java 最具吸引力的特性之一。J ava虚拟机有自己完善的 硬体 架构,如 处理器 、 堆栈 、 寄存器 等,还具有相应的 指令 系统。JVM屏蔽了与具体 操作系统 平台相关的信息,使得Java 程序

【转】Java Crash原因汇总

冷暖自知 提交于 2019-12-01 06:34:08
如果是Java进程不知道什么原因退出或被杀死,想要分析具体原因,一般来说分下面几步: 1. 拿到Java应用程序的日志文件 2. 查找JVM的致命错误日志 3. 查找操作系统的core dump文件 4. 使用Dtrace查找“是谁杀死了Java进程 1. 拿到Java应用程序的日志文件 一般来说日志文件中会有很应用相关的错误信息。Java进程异常退出的原因最有可能就是应用程序本身的问题。因此检查Java应用程序的日志文件可能是最快定位到错误的方法。 2. 查找JVM的致命错误日志 如果应用程序日志文件中没有发现什么线索。那么还可以查看 JVM的致命错误日志。有些致命的错误,比如JNI或虚拟机本身产生的错误,可能使得Java应用程序来不及写日志就退出了。这时候可以查一个以 "hs_err_pid" 开头的日志名,例如hs_err_pid1125.log,其中1125是进程号。这个文件中也记录了一些宝贵的信息来提供一些线索,特别是Java自身的一些Bug。这个文件一般为于当前的工作目录中。用户可以用find命令自己搜索到。 3. 查找操作系统的core dump文件 作为被操作系统所调度的进程,Java进程也会在不同的信号下产生Core Dump文件,例如Sig_ill和Seg_segv。这些非常严重的错误的确会使得Java虚拟机根本来不及产生任何日志就宕了。拿到core

一次FULL GC问题的排查

非 Y 不嫁゛ 提交于 2019-11-30 06:05:32
一、背景 线上一个项目,每次机器重启时项目都会报出大量的Timeout,同时每个集群节点都被监控到较为频繁的Full GC。之后同事虽然尝试过JVM调优并适当调大了老年代空间,但依然不能根本上解决问题。当时该问题被初步归咎于系统中整合的Groovy,但并未证实。问题汇总如下: 问题一:项目启动时报出大量Timeout; 问题二:项目运行时,频繁Full GC; 随后,我着手做另外一个项目GLUE,该项目同样需要整合Groovy,在做并发测试时,我发现了同样的问题。 经过排查并做出优化,新项目GLUE在并发测试下基本不存在Full GC的问题,在此将问题处理过程记录如下,希望可以给大家一点参考。 二、分析 新系统GLUE底层基于Groovy实现,系统通过执行 “groovy.lang.GroovyClassLoader.parseClass(groovyScript)” 进行Groovy代码解析,Groovy为了保证解析后执行的都是最新的脚本内容,每进行一次解析都会生成一次新命名的Class文件,底层代码如下图: 因此,如果Groovy类加载器设置为单例,当对脚本(即使同一段脚本)多次执行该方法时,会导致 “GroovyClassLoader” 装载的Class越来越多。如果此处临时加载的类不能够被及时释放,最终将会导致PermGen OutOfMemoryError

【转】Java虚拟机(JVM)中的内存设置详解

断了今生、忘了曾经 提交于 2019-11-30 05:34:44
在一些规模稍大的应用中,Java虚拟机(JVM)的内存设置尤为重要,想在项目中取得好的效率,GC(垃圾回收)的设置是第一步。 PermGen space:全称是Permanent Generation space.就是说是永久保存的区域,用于存放Class和Meta信息,Class在被Load的时候被放入该区域Heap space:存放Instance。 GC(Garbage Collection)应该不会对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误 Java Heap分为3个区 1.Young 2.Old 3.Permanent Young区保存刚实例化的对象。当该区被填满时,GC会将对象移到Old区。Permanent区则负责保存反射对象,本文不讨论该区。 JVM的Heap分配可以使用-X参数设定, -Xms 初始Heap大小 -Xmx java heap最大值 -Xmn young generation的heap大小 JVM有2个GC线程 第一个线程负责回收Heap的Young区 第二个线程在Heap不足时,遍历Heap,将Young 区升级为Older区 Old区的大小等于-Xmx减去-Xmn,不能将-Xms的值设的过大,因为第二个线程被迫运行会降低JVM的性能。 为什么一些程序频繁发生GC

如何识别Java中的内存泄漏

丶灬走出姿态 提交于 2019-11-29 23:25:26
内存泄漏的识别 在将程序部署到生产环境之前检查一下是否存在内存泄漏的问题是很有必要的。这里可以通过垃圾收集器的指标来进行初步的判断。 如GC后内存使用仍然持续上升,那么就可能有内存泄漏的问题,比如上面的这幅图,代码可以查看GitHub(https://gist.github.com/dpryden/b2bb29ee2d146901b4ae)。不过在现实中内存像图上一样线性增加的可能性是很小的,见图Old Gen,而GC suspension times或者Eden Space和Survivor空间使用并不足以识别出内存泄漏。 缩小问题的范围 要找出内存泄漏的原因当下已经有许多工具可用,比如JVisualVM或者jStat。这些工具是JDK自带的,所以大家随时都能用。除了要识别一些常用的内部Java类,一些用户自定义累同样需要识别。 性能优化 在日常的开发过程中,只要GC没有影响到性能,开发者就不会去关注内存设置于配置。从而埋下了潜在的隐患:因为内存问题并不只有溢出和泄露,GC时间过长同样会造成这个问题。比如下图中GC占用了16%的CPU。 Heap设置 Heap太小会导致频繁的GC,从而情景不难想象:增加GC会消耗更多的CPU,同时在GC时JVM会被冻结,最后导致一个很差的性能。总的来说,Heap太小的话,虽然GC时间变短,但是会变得更加频繁。 Heap太大会导致GC时间边长

Tomcat中JVM内存溢出及合理配置

爱⌒轻易说出口 提交于 2019-11-29 23:22:33
Tomcat本身不能直接在计算机上运行,需要依赖于硬件基础之上的操作系统和一个Java虚拟机。Tomcat的内存溢出本质就是JVM内存溢出,所以在本文开始时,应该先对Java JVM有关内存方面的知识进行详细介绍。 一、Java JVM内存介绍 JVM管理两种类型的内存,堆和非堆。按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中,它和堆不同,运行期内GC不会释放其空间。 (1). 堆内存分配 JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指 定,默认是物理内存的1/4。默认空余堆内存小于 40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、 -Xmx相等以避免在每次GC 后调整堆的大小。可以利用JVM提供的-Xmn -Xms

Android 调试查看内存使用情况

半腔热情 提交于 2019-11-29 13:42:41
如果想查看整个内存可以使用命令: cat /proc/meninfo 查看应用程序的命令:adb shell procrank 显示如下: PID Vss Rss Pss Uss cmdline 190 79560K 74736K 49624K 43604K system_server 14335 55776K 55740K 31308K 26676K com.android.launcher2 13074 47408K 47380K 24947K 22428K com.android.settings 7626 42060K 42028K 21312K 18432K com.android.systemui 13948 32992K 32944K 11687K 9800K android.process.acore 283 25516K 25476K 8136K 7148K com.android.phone 422 24560K 24524K 7338K 6292K com.android.inputmethod.pinyin 12871 25804K 25740K 6288K 4880K com.snda.tt 454 23672K 23616K 5735K 4544K com.google.process.gapps 14723 25744K 25684K 5706K

Netty5_内存管理_源码讲解

佐手、 提交于 2019-11-28 15:55:14
欢迎大家关注我的微博 http://weibo.com/hotbain 会将发布的开源项目技术贴通过微博通知大家,希望大家能够互勉共进!谢谢!也很希望能够得到大家对我博文的反馈,写出更高质量的文章!! read事件发生,Netty需要从内核中读取数据到自己内部可以管辖的缓冲区,怎么进行分配?使用完毕后,怎么释放?已经write方法调用,怎样将相应数据进行缓冲区分配,以及write事件发生,flush完成后,怎样将缓冲区释放? read内存分配 要知道read是怎样进行进行内存分配的首先要知道是什么进行分配的,分配完之后,怎么进行内存回收?每次分配新的ByteBuf大小是多少? 分配内存:假设是初次进行分配(同一个socket多次进行分配的情况,后面会讲到.),我们看一下是什么时候进行分配的.上代码: int byteBufCapacity = allocHandle.guess(); int totalReadAmount = 0; do { //可能是 direct或者 heap 从与当前socket相关的allocator得到byteBuf数组 // byteBuf =allocHandle.allocate(allocator); byteBuf = allocator.ioBuffer(byteBufCapacity); int writable = byteBuf

文本在内存中的编码(3)——乱码探源(6)

自闭症网瘾萝莉.ら 提交于 2019-11-28 14:39:47
先讲个小故事,虽然跟主题有点不太相关哈: 唐朝诗人李绅,身为官员,脾气暴躁,瞧不起信教的,尤其鄙视装逼之僧人,动不动就对他们拳脚相加。曾扬言:“我可以接见他们,要能答出来还好,要是答不出来,我弄死他!”有一回一个和尚来跟他宣传因果报应,李绅问:“阿师 从哪里来,到哪里去呢 ?”僧答:“贫僧 从来处来,到去处去 。”李绅当时就急了, 撸起袖子,亮出了手腕:“我去年买了个表!” 来自知乎问答“ 古人是如何「装逼」的? ”,略有改动。 String到哪里去? 有了前面僧人的教训,在这里就不故弄玄虚了,应该说String的去处还是蛮确定的,那就是到byte[]中去,方式就是通过getBytes这一方法。 new String与getBytes 如果说new String(byte[], encoding)是从byte[]到String的过程,那么getBytes(encoding)则正好与之相反:它是从String到byte[]的过程。 或许我们应该说,它从去处来,又到来处去。 编码的逆转 显然,我们一直在说,String也不过是一堆byte,getBytes的过程不过是UTF-16编码的byte[]再转回去其它编码的byte[]的过程。无论是new String还是getBytes,不过都是在玩编码的转换而已。 从上图中可以看出String作为桥梁

new/delete 和 malloc/free有什么区别和联系

穿精又带淫゛_ 提交于 2019-11-28 12:53:38
区别: 1. new/delete是 C++的操作符,malloc/free是C/C++标准库函数 。 2. new分为两步的:第一步是申请内存,第二步则是调用构造函数初始化对象。同样,在调用delete的时候,需要先调用析构函数,然后再回收堆内存。malloc只会根据参数分配内存,默认返回指向void*的指针,同样free释放malloc分配的内存。 3.malloc/free是 new/delete的一个子集。 共同点: 1. 都必须配对使用,这里的配对使用,可不能理解为一个new/malloc就对应一个delete/free,而是指在作用域内,new/malloc所申请的内存,必须被有效释放,否则将会导致内存泄露。 2. 都是申请内存,释放内存。 示例: //pM指针指向sizeof(int)*100大小的内存块 int* pM = (int *)malloc(sizeof(int)*100); if (pM) { free(pM); pM = NULL; } //pN创建100个int对象 int* pN = new int[100]; if (pN) { delete []pN; pN = NULL; } 来源: oschina 链接: https://my.oschina.net/u/70773/blog/295907