Springboot开发的应用为什么这么占用内存


Java的原罪

Java 程序员比 c或者是c++程序员相比轻松了很多.
不要管理繁杂的内存申请与释放,也不用担心因为忘记释放内存导致很严重的内存泄漏. 因为JAVA使用GC 垃圾回收的机制实现了内存的自动管理. 自凡是自动管理, 就需要有单独的内存空间来存放相应的工具和管理数据. 就导致需要时用更多的内存 现阶段JVM的GC管理器关注点并不在于 如何减少内存的分配与消耗,
而是主要目的在于减少FullGC导致的STW, 避免会影响业务 因为内存越来越便宜,这也就导致了内存的使用更加泛滥. JAVA 本身就是运行与JVM虚拟机的, 本身就需要消耗一定的资源进行管理与优化.
这是JAVA应用内存的最底层的原因之一.

Java内存管理的繁杂

1. JAVA运行时的是依赖于JVM进行源代码的解析与运行.
运行JVM和JVM解析运行代码都需要内存.而且需要的往往很多.
2. JAVA内存管理 大体上可以分为 堆区和非堆区
3. 非堆区解释起来比较复杂: 有直接内存, 有栈区, 有方法区, 有类加载器, GC,解释器,编译器,等等工具.
每种工具都需要内存来存储. 比较多的是 方法区, 栈区, 直接内存.
3.1 类被加载,编译后会把编译好的方法放到方法区, 这个里面一般至少会预留 240M左右的内存,
如果程序非常复杂,方法区应该适当扩容, 因为他的作用跟Oracle的shared pool类似. 缓存了编译优秀的方法
如果空间不够,会被GC掉, 这样下次再调用时需要再次进行解析编译, 会浪费CPU周期和增加相应时间.
3.2 直接内存, ERP应用并不像是科学计算, 他需要大量的输入输出, 需要大量的文件读写,数据库访问.
java需要开辟很多内存通过类似于map的方式进行映射到file, 方便快速进行读取和写入以便提高性能.
如果是有的文件都需要加载到内存才能够进行读写的话, 堆区的压力会很大, GC会很大, 性能也会衰退
所以还是有必要保留一些内存用于直接内存与系统,与数据库进行交互.
3.3 栈区, linux上面一个栈大约有1M内存的大小. 一般情况下一个java应用负载一些 200个左右的线程数量是很正常的
这就意味着至少有200M左右的内存作为栈内存进行使用.
3.4 GC,类加载,解释器,编译器. 工具都需要内存进行处理, 很多类加载器还需要跟踪类的调用次数. GC需要记录类的层级
这些工具都需要使用内存进行运行和管理数据.
3.5 在一个大型应用中, 非堆区超过1G内存也是很正常的. 不能小看非堆区内存, 不能过量的扩大堆区
需要避免出现非地区导致的OOM或者是栈溢出的问题. 4.1 堆区内存就比较好理解了. 提高JAVA性能的几个方法里面一直有加大堆区, 改用好的GC算法等.
可以简单理解为方法区存放的是类的一些定义, 堆区存放的是类的实例化的对象.
方法区内的类和方法 在堆区都会有多倍甚至是无数倍的实例化对象. (单例的话会少一些) 堆区中还有一些简单的数组, 一些dataset 查询展示的对象, 文件实例化的格式化数据等等内容
堆区如果过小, 会不停地进行GC, 一方面导致CPU增加,一方面会导致产品相应变慢, 5. 所有的性能都不是平白无故产生的. 要么是空间换时间, 要么是时间换空间.
java明显就是使用空间换时间的一种方法.
与linux的buffer cache 和 oracle的 db buffer 一样. 缓存到内存是提高性能的最便宜的方法. 内存不是越小越少, 如果仅是进行一些计算,可以使用低内存, 高CPU占比
但如果是重流程,重数据的业务应用, 建议流出足够的内存进行缓存, 避免GC来提高性能.

Springboot的推波助澜

springboot开创性的AOP和IOC 会导致springboot的框架需要自行管理很多内容.
bean的实例化和管理不仅仅会导致启动变慢, 也会导致内存的更多使用. springboot本身框架里面就会有比较多的组件, 每种组件都需要使用内存进行存储和实例化
这就增加了内存的使用. IOC实际上解放了开发是 进行 new object的过程, 这也导致框架内必须存储好 bean(懒加载除外)
类或者是bean多了 管理和寻找都会成为课题, 为了性能不得不启用更加负责的内存, 索引等类型导致内存使用量增加.

ERP应用的特定场景

ERP 的核心是数据,业务和流程.
这三者都需要大量的内存进行处理 一个大型的查询,虽然可以走到数据库分页, 但是内存中不可避免的出现大量的dataset等对象用于存储和展示.
虽然很多数据可以共享.
但是ERP严格要求数据权限的高标准
导致很多内存对象无法进行共享,不然会出现数据泄密
这就导致在高并发情况下内存的使用量可能会翻倍的激增. 产品的流程特别复杂时需要缓存各个流程的多个节点信息,便于展示和直接使用
每多一个节点的展示,需要的内存就会更加的多. ERP还有很多打印和渲染的需求, 因为不能到客户端渲染(很难加水印,并且篡改非常简单)
会导致服务端的内存大量增加. 现在ERP为了更加好看, 和更加安全往往有很多优秀的特性. 特性都是需要花钱和内存的, 这会恶化内存的使用.

快速响应的要求

在很多审批和展示的环节领导要求越来越高, 甚至要求集团层次的查询要秒级出结果
这其实是很难的. 唯一的解决方案只能是预读和缓写 预读的话需要将要展示的数据缓存到java的内存
缓写的话需要增加各种措施来保证一致性. 虽然可以拆分SU来进行内存的拆解
但是上面谈到的几点内存使用基本上是无法避免的

数据库是及其昂贵的

现阶段大部分ERP还都是使用集中式的数据库来存储数据
集中式的数据库是非常金贵的资源
在高并发大数据量的情况下几乎是很难实现快速响应的. 为了减少对数据库的以来. JAVA应用可以缓存很多数据进入内存中.
虽然那也可以使用redis, 消息队列等方式进行缓解, 但是redis和消息队列的过度使用会是性能杀手 适当的内存使用对性能,稳定性,尤其是数据库的稳定性是非常有裨益的.

Springboot开发的应用为什么这么占用内存的更多相关文章

  1. 使用SpringCloud实现的微服务软件开发部署到Linux上占用内存过大问题解决办法

    问题描述 最近上线的一个使用JAVA的Spring Cloud开发的ERP软件,部署上线时发现很严重的内存资源占用过高问题,而实际上开发测试并没有很大的访问量,甚至却出现了服务器无法正常访问的现象. ...

  2. java优化占用内存的方法(一)

    java做的系统给人的印象是什么?占 内存!说道这句话就会有N多人站出来为java辩护,并举出一堆的性能测试报告来证明这一点.其实从理论上来讲java做的系统并不比其他语言开发出来的 系统更占用内存, ...

  3. 【转载】Unity 优雅地管理资源,减少占用内存,优化游戏

    转自:星辰的<Unity3D占用内存太大的解决方法> 最近网友通过网站搜索Unity3D在手机及其他平台下占用内存太大. 这里写下关于Unity3D对于内存的管理与优化. Unity3D  ...

  4. android 图片占用内存与什么有关

    android 图片占用内存与什么有关 原文链接:http://blog.csdn.net/zjl5211314/article/details/7041813 在开发手机应用的时候,内存是有限的,那 ...

  5. Unity3D占用内存太大的解决方法

    原地址:http://www.cnblogs.com/88999660/archive/2013/03/15/2961663.html 最近网友通过网站搜索Unity3D在手机及其他平台下占用内存太大 ...

  6. 图片--android 图片占用内存与什么有关

    原文链接:http://blog.csdn.net/zjl5211314/article/details/7041813 在开发手机应用的时候,内存是有限的,那使用的时候,就要合理的运用和释放. 那么 ...

  7. Android开发优化之——对Bitmap的内存优化

    http://blog.csdn.net/arui319/article/details/7953690 在Android应用里,最耗费内存的就是图片资源.而且在Android系统中,读取位图Bitm ...

  8. Android中图片占用内存的计算

    Android中图片占用内存的计算 原文链接 http://blog.sina.com.cn/s/blog_4e60b09d01016133.html   在Android开发中,我现在发现很多人还不 ...

  9. SpringBoot开发案例之多任务并行+线程池处理

    前言 前几篇文章着重介绍了后端服务数据库和多线程并行处理优化,并示例了改造前后的伪代码逻辑.当然了,优化是无止境的,前人栽树后人乘凉.作为我们开发者来说,既然站在了巨人的肩膀上,就要写出更加优化的程序 ...

  10. 设置Redis最大占用内存

    https://blog.csdn.net/happyrabbit456/article/details/54945667 Redis需要设置最大占用内存吗?如果Redis内存使用超出了设置的最大值会 ...

随机推荐

  1. Python——第四章:匿名函数(lambda 函数)

    匿名函数也被称为 lambda 函数 lambda 函数是一种小型.一次性的.可以在一行内定义的匿名函数.它通常用于一些简单的操作,例如传递给高阶函数(接受函数作为参数的函数)或在一行内定义短小的功能 ...

  2. java后端工具类之从0到1生成数字证书(RSA)

    开放签电子签章系统-开源版这周(2023-12-15)就要上线发布了,为了让开源版能够更好的服务广大研发工程师,接下来会详细的说说开源版从代码层面的具体实现,以便大家在工作过程中更好使用开放签电子签章 ...

  3. ZincSearch轻量级全文搜索引擎入门到

    ZincSearch轻量级全文搜索引擎入门到 Zinc是一个用于对文档进行全文搜索的搜索引擎.它是开源的,内置在 Go 中.Zinc不是从头开始构建索引引擎,而是构建在 bluge 之上,这是一个出色 ...

  4. Luogu P4592 [TJOI2018]异或 做题记录

    随机跳的. 树上维护序列,显然树剖.维护异或,显然 01trie. 01trie 维护区间异或,显然可持久化一下. 看到时限很大,显然可以双 log. 于是跑一边树剖,再根据 id 暴力建一个 可持久 ...

  5. const 方法可以改变(智能)指针成员指向的对象

    <C++ Primer 5th> P406 const 方法,不能修改指针本身,但是可以修改指针指向的对象! class Foo { public: Foo() : c(new int() ...

  6. 如何使用loki查询日志中大于某一数字的值的日志

    简介 loki是一款轻量级的日志收集中间件,比elk体系占用的内存更小,采用go语言开发,可以利用grafana来查询loki中存储的日志,loki存储日志只对提前预设的标签做索引,所以日志存储空间占 ...

  7. 前端js常用的60余种工具方法【强烈建议收藏】

    "工欲善其事,必先利其器!"本文为大家带来前端js开发常用的60种工具方法,有了这些开发工具你就可以高效的处理任务和信息了. 1.邮箱 export const isEmail = ...

  8. 如何在iPhone设备中查看崩溃日志

    ​ ​如何在iPhone设备中查看崩溃日志 目录 如何在iPhone设备中查看崩溃日志 摘要 引言 导致iPhone设备崩溃的主要原因是什么? 使用克魔助手查看iPhone设备中的崩溃日志 奔溃日志分 ...

  9. Linux 创建新用户

    添加用户组[root@VipSoft ~]#groupadd admin 添加用户[root@VipSoft ~]#useradd jimmy -m -d /home/jimmy -g admin 修 ...

  10. Kubernetes(K8S) 监控 Prometheus + Grafana

    监控指标 集群监控 节点资源利用率 节点数 运行Pods Pod 监控 容器指标 应用程序 Prometheus 开源的 监控.报警.数据库 以HTTP协议周期性抓取被监控组件状态 不需要复杂的集成过 ...