首页
Search
1
JAVA线程池总结
976 阅读
2
Redis学习笔记
963 阅读
3
JAVA垃圾回收
925 阅读
4
Kafka、RocketMQ消息队列总结
912 阅读
5
Flink on Kubernetes 计算和存储分离落地实践
894 阅读
大数据
Flink
后端
Java
笔记
运维
游客
Search
标签搜索
大数据
Flink
离线
实时
Redis
OpenJDK
Java
笔记
JVM
Elasticsearch
GC
Hadoop
Hudi
Flink CDC
K8S
数据湖
TOTC
累计撰写
307
篇文章
累计阅读
104.3万
次
首页
栏目
大数据
Flink
后端
Java
笔记
运维
页面
搜索到
5
篇与
Java
的结果
返回首页
2020-01-11
JVM垃圾收集行为分析方法
尽管某些监控工具,如:jvisualvm,可以实时提供垃圾收集图表和指标,但它们并没有提供GC行为完整的详细信息,GC日志是研究垃圾收集行为的最佳信息来源。启用GC日志 可以通过指定以下JVM参数来启用GC日志:Java 8及以下版本-XX:+PrintGCDetails -Xloggc:<gc-log-file-path> Example: -XX:+PrintGCDetails -Xloggc:/opt/tmp/myapp-gc.logJava 9及以上版本-Xlog:gc*:file=<gc-log-file-path> Example: -Xlog:gc*:file=/opt/tmp/myapp-gc.log注意事项 一般需要观察24小时的GC日志,这样就会同时看到高流量和低流量的情况。 建议从生产环境中收集GC日志,因为垃圾收集行为受流量模式的影响很大,在测试环境中很难模拟生产流量。我们进行2次测试:基线测试——使用JMeter工具在没有启用垃圾收集GC日志的情况下运行应用程序20分钟,同时有200个并发用户。GC日志启用测试——使用相同的JMeter脚本运行应用程序并启用垃圾收集GC日志,持续时间为20分钟,同时有200个并发用户。对比结果如下:如图所示,CPU和内存消耗没有明显差异,同样,平均响应和事务吞吐量也没有明显差异,通过实验可以看出,GC日志在生产服务器中增加的开销可以忽略不计。分析工具 捕获GC日志后,可以使用以下免费工具之一来分析GC日志:1.GCeasy 2.IBM GC & Memory visualizer 3.HP Jmeter4.Garbage Cat
2020年01月11日
615 阅读
13 点赞
2019-01-06
JAVA垃圾回收
垃圾回收算法 标记-清除算法 :产生不连续的内存碎片,为较大对象分配内存时无法找到足够连续的内存,不得不提前触发垃圾收集动作。CMS垃圾回收器。标记-整理算法 :存活的对象向一端移动,存活率高时,效率远高于复制算法。G1、ParallelGC(Paraller Old)。复制算法 :Eden、s0、s1,比例是8:1:1,10%被浪费,JDK8,ParallelGC(Parallel Scavenge)。分代收集算法 。{lamp/}垃圾回收器 CMS收集器 :发标记、并发清除、内存碎片、最短回收停顿时间为目标,与用户线程可以并发执行,牺牲一定的吞吐量;可开启内存碎片整理,会停顿用户线程。ParallelGC :(JDK8)新生代(Parallel Scavenge复制算法),老年代(Paraller Old标记整理算法)。G1垃圾收集器 :吞吐量高,可预测的停顿;整体基于标记-整理算法,从局部(两个Region)是基于复制算法;设置了新生代大小相当于放弃了G1为我们做的自动调优。G1官方的建议——实时数据占用了超过半数的堆空间;对象分配率或“晋升”的速度变化明显;期望消除耗时较长的GC或停顿(超过0.5——1秒)。ZGC :着色指针(在对象的引用上标注了对象的信息),读屏障(把指针更新为有效地址再返回,也就是,永远只有单个对象读取时有概率被减速),Stop-The-World 只会在根对象扫描阶段发生,所以GC暂停时间并不会随着堆和存活对象的数量而增加。TB 级别的堆内存管理;最大 GC Pause 不高于 10ms;最大的吞吐率(Throughput)损耗不高于 15%。ParallelGC 吞吐量优先,后台运算而不需要太多交互的任务。CMS 响应速度优先,集中在互联网站或B/S系统服务端上的Java应用。G1 响应速度优先,面向服务端应用,将来替换CMS。{lamp/}内存划分为 JVM内存划分为堆内存和非堆内存,堆内存分为年轻代、老年代,非堆内存就一个永久代。在JDK1.8版本废弃了永久代,替代的是元空间(MetaSpace),元空间与永久代上类似,都是方法区的实现,他们最大区别是元空间并不在JVM中,而是使用本地内存。{lamp/}Full GC条件 a.发生minor gc之前会判断老年代最大可用连续空间是否大于新生代的所有对象总空间,如果大于直接发生minor gc,如果小于发生full gc。b.老年代空间不足时,创建一个大对象时Ended放不下,会直接保存到老年代中,如果老年代空间不足,就会触发full gc。c.显示调用System.gc()方法,可能会发生full gc。{lamp/}引用类型 强引用 :永远不会回收软引用SoftReference :内存不足时才会回收该对象。比如网页缓存、图片缓存等。弱引用WeakReference :每次垃圾回收。虚引用PhantomReference :虚引用必须和引用队列 (ReferenceQueue)联合使用,主要用来跟踪对象被垃圾回收器回收的活动。假如有一个应用需要读取大量的本地图片,如果每次读取图片都从硬盘读取,则会严重影响性能,但是如果全部加载到内存当中,又有可能造成内存溢出,此时使用软引用可以解决这个问题。
2019年01月06日
925 阅读
21 点赞
2017-12-03
金融项目微调OpenJDK,编译源码
系统版本:Ubuntu 16.04 LTS系统类型:64位操作系统编译出来的是64位的JDK,可以通过设置参数--with-target-bits=32生成32位编译结果。OpenJDK源码下载 https://hg.openjdk.java.net/jdk8/jdk8,点击左侧zip下载到到本地直接解压即可。微调源码使该JDK编译打包后的jar其他JDK无法识别,应用系统必须和JDK配套部署,例如银行自己开发的一套企业金融资产管理系统,交付第三方财务公司使用时,同时提供jar包和JDK,这样就增强了系统的安全性。安装GCC或CLang,例如,安装GCC的命令为:sudo apt-get install build-essential在编译过程中需要依赖FreeType、CUPS等若干第三方库,OpenJDK全部的依赖库如下:OpenJDK除了使用C、C++编写外,还使用了Java语言,因此还需要一个编译期可用的小版本JDK(如JDK7),官方称为“Bootstrap JDK”。编译命令:1.执行bash configure --enable-debug --with-jvm-variants=serverconfigure会检查依赖项、参数配置和构建输出目录结构等。2.执行make images编译整个OpenJDK,images(product-images)是编译出整个JDK镜像,其他参数还有:hotspot:只编译HotSpot虚拟机 hotspot-<variant>:只编译特定模式的Hot Spot虚拟机 docs-image:产生JDK的文档镜像 test-image:产生JDK的测试镜像 all-images:相当于连续调用product、docs、test三个编译目标 bootcycle-images:编译两次JDK,其中第二次使用第一次的编译结果作为Bootstrap JDK clean:清理make命令产生的临时文件 dist-clean:清理make和configure命令产生的临时文件编译后产生的JDK路径:build/配置名称/jdk,把它复制到JAVA_HOME目录,就可以作为一个完整的JDK来使用。重新编译前先执行make clean和makedist-clean命令清理目录。
2017年12月03日
1,238 阅读
43 点赞
2014-01-04
“锁”相关总结
synchronized 1.JDK 6之后,synchronized目前锁一共有4种状态,级别从低到高依次是:无锁、偏向锁、轻量级锁和重量级锁。锁状态只能升级不能降级。偏向锁,一段同步代码一直被一个线程所访问,那么该线程会自动获取锁,降低获取锁的代价。轻量级锁,是指当锁是偏向锁的时候,被另外的线程所访问,偏向锁就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,从而提高性能。重量级锁,若当前只有一个等待线程,则该线程通过自旋进行等待。但是当自旋超过一定的次数,或者一个线程在持有锁,一个在自旋,又有第三个来访时,轻量级锁升级为重量级锁。重量级锁,除了拥有锁的线程以外的线程都阻塞。{lamp/}ReentrantLock Synchronized,Java虚拟机完成,不公平锁,ReentrantLock和synchronized都是可重入锁。ReentrantLock,类层面的实现,户自己去操作,可以指定锁是公平的还是非公平的。NonReentrantLock,不可重入锁。ReentrantLock更灵活,在Hashtable和ConcurrentHashMap中体现得淋漓尽致synchronized的话,锁的范围是整个方法或synchronized块部分;而Lock因为是方法调用,可以跨方法,灵活性更大。和synchronized相比,ReentrantLock提供给用户多种方法用于锁信息的获取,比如可以知道lock是否被当前线程获取、lock被同一个线程调用了几次、lock是否被任意线程获取等等。ReentrantLock的某些方法可以决定多长时间内尝试获取锁,如果获取不到就抛异常,这样就可以一定程度上减轻死锁的可能性,如果锁被另一个线程占据了,synchronized只会一直等待,很容易错序死锁。之后,synchronized做了诸多优化,效率上synchronized和ReentrantLock应该是差不多。{lamp/}公平锁 VS 非公平锁 公平锁:线程直接进入队列中排队,等待队列中除第一个线程以外的所有线程都会阻塞,优点是等待锁的线程不会饿死,缺点是整体吞吐效率相对非公平锁要低。非公平锁:如果此时锁刚好可用,线程有几率不阻塞直接获得锁,CPU不必唤醒所有线程,缺点是处于等待队列中的线程可能会饿死,或者等很久才会获得锁。{lamp/}乐观锁 VS 悲观锁 {lamp/}自旋锁 VS 适应性自旋锁 自旋锁:自旋等待虽然避免了线程切换的开销,但它要占用处理器时间。如果锁被占用的时间很短,自旋等待的效果就会非常好。反之,如果锁被占用的时间很长,那么自旋的线程只会白浪费处理器资源。适应性自旋锁:自适应意味着自旋的时间(次数)不再固定,而是由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定。{lamp/}可重入锁 VS 非可重入锁 可重入锁,又名递归锁,是指在同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提锁对象得是同一个对象或者class),不会因为之前已经获取过还没释放而阻塞。{lamp/}独享锁 VS 共享锁 ReentrantLock和ReentrantReadWriteLock{lamp/}volatile 当写一个volatile变量时,JMM会把该线程对应的本地内存中的变量强制刷新到主内存中去,导致其他线程中的缓存无效。volatile是一种轻量级的同步机制,一是保证共享变量对所有线程的可见性;二是禁止指令重排序优化。volatile对于单个的共享变量的读/写具有原子性,但是像num++这种复合操作,volatile无法保证其原子性。可以用num.incrementAndGet()。
2014年01月04日
683 阅读
52 点赞
2013-06-29
JAVA线程池总结
Executors类提供了4种不同的线程池 1.newCachedThreadPool ——SynchronousQueue2.newFixedThreadPool ——LinkedBlockingQueue3.newScheduledThreadPool4.newSingleThreadExecutor ——LinkedBlockingQueue{lamp/}参数 corePoolSize 线程池核心线程大小。maxPoolSize 线程池最大线程数量,如果工作队列满了,才会创建一个新线程。keepAliveTime 空闲线程存活时间。unit 空间线程存活时间单位,keepAliveTime的计量单位。{lamp/}workQueue 工作队列 ArrayBlockingQueue :生产和消费用的是同一个锁;必须指定大小(有界)。LinkedBlockingQueue :锁是分离的;转换为Node<E>进行插入或移除、会生成额外的Node对象、对GC有影响都可以;不指定大小时(无界),生产速度大于消费速度时候,有可能会内存溢出。PriorityBlockingQueue SynchronousQuene ,newCachedThreadPool,操作必须是放和取交替完成。threadFactory,设定线程名、是否为daemon线程,守护线程。allowCoreThreadTimeoutRejectedExecutionHandler 拒绝策略 AbortPolicy ,丢弃任务并抛出异常,默认。DiscardPolicy ,丢弃任务。DiscardOldestPolicy ,丢弃队列最前面的任务,然后重新提交被拒绝的任务。不和优先级队列同时使用。CallerRunsPolicy ,由调用线程处理该任务 导致程序阻塞,性能效率上必然的损失较大。{lamp/}默认配置 corePoolSize = 1 queueCapacity = Integer.MAX_VALUE maxPoolSize = Integer.MAX_VALUEkeepAliveTime = 60秒 allowCoreThreadTimeout = false rejectedExecutionHandler = AbortPolicy(){lamp/}corePoolSize、maxPoolSize根据机器资源配置相同的值根据峰值持续的时间设置allowCoreThreadTimeout = true、keepAliveTime来动态控制存活线程的数量。自定义任务队列,可以根据当前并发量,通过简单的管理页面随时动态调整队列的长度(保证线程安全的前提下)。{lamp/}ThreadLocal 每个线程都会有这个变量的一个副本。Thread类中有两个变量,是ThreadLocal.ThreadLocalMap ThreadLocalMap的key是ThreadLocal的弱引用,在没有其他地方对ThreadLoca依赖时,ThreadLocalMap中的ThreadLocal对象就会被回收掉,但是对应的value不会被回收,Map中就可能存在key为null但是value不为null的项,所以使用完毕及时调用remove方法避免内存泄漏。
2013年06月29日
976 阅读
85 点赞