首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >(十五)ThreadLocal的用法,如何解决内存泄漏

(十五)ThreadLocal的用法,如何解决内存泄漏

作者头像
HaC
发布于 2020-12-30 09:58:41
发布于 2020-12-30 09:58:41
1.4K00
代码可运行
举报
文章被收录于专栏:HaC的技术专栏HaC的技术专栏
运行总次数:0
代码可运行

什么是ThreadLocal变量

ThreadLocal称为线程本地变量,其为变量在每个线程中都创建了一个副本,每个线程都访问和修改本线程中变量的副本,但每个线程之间的变量是不能相互访问的,ThreadLocal不是一个Thread。

ThreadLocal 有四个方法:

ThreadLocal作用

  1. ThreadLocal可以让线程独占资源,存储于线程内部,避免线程堵塞造成CPU吞吐下降。
  2. 使用同一个threadLocal ,但每个线程的变量是独立都,对其他线程不可见,不需要每个线程都 new 一个对象,减少了内存的开销。

ThreadLocal方法详解

demo:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ThreadLocalTest {

    public static void main(String[] args) {

        ThreadLocal<Integer> threadLocal = new ThreadLocal<>();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    threadLocal.set(1);
                    System.out.println(threadLocal.get());
                }finally {
                    threadLocal.remove();
                }
            }
        }, "Thread1").start();


        new Thread(new Runnable() {
            @Override
            public void run() {
                threadLocal.set(2);
                System.out.println(threadLocal.get());
            }
        }, "Thread2").start();


        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(threadLocal.get());
            }
        }, "Thread3").start();
    }

}

输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1
2
null

可以看到,每个线程使用都是对同一个threadLocal的引用,但是线程之间的变量是不能互相访问的。

ThreadLocal如何创建副本的?(如何维护变量的)

在每个Thread中包含一个ThreadLocalMap,ThreadLocalMap的key是ThreadLocal的对象,value是独享数据。

每个Thread 维护一个 ThreadLocalMap 映射表,这个映射表的 key 是 ThreadLocal实例本身,value 是真正需要存储的 Object。

也就是说 ThreadLocal 本身并不存储值,它只是作为一个 key 来让线程从 ThreadLocalMap 获取 value。

ThreadLocal内存泄漏问题

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static class Entry extends WeakReference<ThreadLocal<?>> {
    /** The value associated with this ThreadLocal. */
    Object value;

    Entry(ThreadLocal<?> k, Object v) {
        super(k); //继续深扒,key 是一个弱引用,以一个弱引用指向ThreadLcoal对象k
        value = v;
    }
}

ThreadLocalMap 是使用 ThreadLocal 的弱引用作为 Key 的,弱引用的对象在 GC 时会被回收。

ThreadLocalMap使用ThreadLocal的弱引用作为key,如果一个ThreadLocal没有外部强引用来引用它,那么系统 GC 的时候,这个ThreadLocal势必会被回收(为什么会被回收下面讲到),然后ThreadLocalMap中就会出现key为null的Entry,就没有办法访问这些key为null的Entry的value,如果当前线程再迟迟不结束的话,这些key为null的Entry的value就会一直存在一条强引用链:Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value 永远无法回收,造成内存泄漏。

以上总结就是,key为null被回收了,但是value还在,需要在set、get的时候判断才能回收。

那为什么value不能被设置成弱引用呢?

如果vaule设计为弱引用,你可能获取到的是null ,毫无意义。

为什么要使用弱引用而不是强引用?

强引用:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Object object= new Object();

强引用用的最多,无论任何情况下,只要强引用关系还存在,垃圾收集器就永远不会回收掉被引用的对象。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
object =null

对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显式地将相应(强)引用赋值为null,才可以当做垃圾被收集,当然具体回收时机还是要看垃圾收集策略。

而强引用是造成Java内存泄漏的主要原因之一,内存空间不足时,Java虚拟机会抛出OutOfMemoryError ,使程序异常终止,但是注意,抛出错误也不会回收这些强引用的对象。

弱引用:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
String str = new String("123");
WeakReference<String> weakReference = new WeakReference<>(str);
str = null;

在垃圾回收的一个周期内,jvm发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。

所以,弱引用相对强引用来说,生命周期更短。

参考四种引用:https://www.cnblogs.com/yanl55555/p/13365397.html

引用类型

被垃圾回收时间

用途

生存时间

强引用

从来不会

对象的一般状态

JVM停止运行时终止

软引用

当内存不足时

对象缓存

内存不足时终止

弱引用

正常垃圾回收时

对象缓存

垃圾回收后终止

虚引用

正常垃圾回收时

跟踪对象的垃圾回收

垃圾回收后终止

上个图理解一下:

看图,当主线程结束,栈帧销毁,强引用ThreadLocal没有了。再看一下红色部分,

如果是强引用, 线程的ThreadLocalMap里某个entry的 k 引用还指向这个ThreadLocal对象,这样会导致k指向的ThreadLocal对象以及 v 指向的对象都不能被jvm虚拟机gc回收,造成内存泄漏。

如果是弱引用,就可以是ThreadLocal对象在执行完毕的时候被回收了,因为此时只有entry的k弱引用指向它,ThreadLocal回收后,k就指向为null了,但是v还是有值,也会有内存泄漏的风险,并不能保证不会内存泄漏。

那ThreadLocal为什么要使用弱引用而不是强引用呢?

总结 就是是减少严重内存泄漏的风险。

  1. 上面提到,key为弱引用,key为null时,value不为null,导致value无法被回收,引发内存泄漏。
  2. 弱引用尚且有内存泄漏的风险,强引用更加。使用线程池的时候,自定义的线程数不规范,若使用强引用,内存泄漏的风险更高。

如何防止内存泄漏?

上面提到entry的value还会有内存泄漏的风险。

ThreadLocal有通过方法:调用get,set或remove方法时,就会尝试删除key为null的entry,可以释放value对象所占用的内存。

上面demo的正确例子应该是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
new Thread(new Runnable() {
    @Override
    public void run() {
        try{
            threadLocal.set(1);
            System.out.println(threadLocal.get());
        }finally {
            threadLocal.remove(); //用完要remove,防止内存泄漏
        }
    }
}, "Thread1").start();

remove方法核心:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 private void remove(ThreadLocal<?> key) {
            Entry[] tab = table;
            int len = tab.length;
            int i = key.threadLocalHashCode & (len-1);
            for (Entry e = tab[i];
                 e != null;
                 e = tab[i = nextIndex(i, len)]) {
                if (e.get() == key) {
                    e.clear();
                    expungeStaleEntry(i); //调用消除方法
                    return;
                }
            }
        }
        
private int expungeStaleEntry(int staleSlot) {
    Entry[] tab = table;
    int len = tab.length;

    // expunge entry at staleSlot
    tab[staleSlot].value = null;   //把vaule赋值null
    tab[staleSlot] = null; 
    size--;

还有set方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// If key not found, put new entry in stale slot
tab[staleSlot].value = null;
tab[staleSlot] = new Entry(key, value);

参考:

https://blog.csdn.net/qq_33404395/article/details/82356344

https://www.cnblogs.com/shen-qian/p/12108655.html## 什么是ThreadLocal变量

ThreadLocal称为线程本地变量,其为变量在每个线程中都创建了一个副本,每个线程都访问和修改本线程中变量的副本,但每个线程之间的变量是不能相互访问的,ThreadLocal不是一个Thread。

ThreadLocal 有四个方法:

ThreadLocal作用

  1. ThreadLocal可以让线程独占资源,存储于线程内部,避免线程堵塞造成CPU吞吐下降。
  2. 使用同一个threadLocal ,但每个线程的变量是独立都,对其他线程不可见,不需要每个线程都 new 一个对象,减少了内存的开销。

ThreadLocal方法详解

demo:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ThreadLocalTest {

    public static void main(String[] args) {

        ThreadLocal<Integer> threadLocal = new ThreadLocal<>();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    threadLocal.set(1);
                    System.out.println(threadLocal.get());
                }finally {
                    threadLocal.remove();
                }
            }
        }, "Thread1").start();


        new Thread(new Runnable() {
            @Override
            public void run() {
                threadLocal.set(2);
                System.out.println(threadLocal.get());
            }
        }, "Thread2").start();


        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(threadLocal.get());
            }
        }, "Thread3").start();
    }

}

输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1
2
null

可以看到,每个线程使用都是对同一个threadLocal的引用,但是线程之间的变量是不能互相访问的。

ThreadLocal如何创建副本的?(如何维护变量的)

在每个Thread中包含一个ThreadLocalMap,ThreadLocalMap的key是ThreadLocal的对象,value是独享数据。

每个Thread 维护一个 ThreadLocalMap 映射表,这个映射表的 key 是 ThreadLocal实例本身,value 是真正需要存储的 Object。

也就是说 ThreadLocal 本身并不存储值,它只是作为一个 key 来让线程从 ThreadLocalMap 获取 value。

ThreadLocal内存泄漏问题

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static class Entry extends WeakReference<ThreadLocal<?>> {
    /** The value associated with this ThreadLocal. */
    Object value;

    Entry(ThreadLocal<?> k, Object v) {
        super(k); //继续深扒,key 是一个弱引用,以一个弱引用指向ThreadLcoal对象k
        value = v;
    }
}

ThreadLocalMap 是使用 ThreadLocal 的弱引用作为 Key 的,弱引用的对象在 GC 时会被回收。

ThreadLocalMap使用ThreadLocal的弱引用作为key,如果一个ThreadLocal没有外部强引用来引用它,那么系统 GC 的时候,这个ThreadLocal势必会被回收(为什么会被回收下面讲到),然后ThreadLocalMap中就会出现key为null的Entry,就没有办法访问这些key为null的Entry的value,如果当前线程再迟迟不结束的话,这些key为null的Entry的value就会一直存在一条强引用链:Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value 永远无法回收,造成内存泄漏。

以上总结就是,key为null被回收了,但是value还在,需要在set、get的时候判断才能回收。

那为什么value不能被设置成弱引用呢?

如果vaule设计为弱引用,你可能获取到的是null ,毫无意义。

为什么要使用弱引用而不是强引用?

强引用:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Object object= new Object();

强引用用的最多,无论任何情况下,只要强引用关系还存在,垃圾收集器就永远不会回收掉被引用的对象。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
object =null

对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显式地将相应(强)引用赋值为null,才可以当做垃圾被收集,当然具体回收时机还是要看垃圾收集策略。

而强引用是造成Java内存泄漏的主要原因之一,内存空间不足时,Java虚拟机会抛出OutOfMemoryError ,使程序异常终止,但是注意,抛出错误也不会回收这些强引用的对象。

弱引用:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
String str = new String("123");
WeakReference<String> weakReference = new WeakReference<>(str);
str = null;

在垃圾回收的一个周期内,jvm发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。

所以,弱引用相对强引用来说,生命周期更短。

参考四种引用:https://www.cnblogs.com/yanl55555/p/13365397.html

引用类型

被垃圾回收时间

用途

生存时间

强引用

从来不会

对象的一般状态

JVM停止运行时终止

软引用

当内存不足时

对象缓存

内存不足时终止

弱引用

正常垃圾回收时

对象缓存

垃圾回收后终止

虚引用

正常垃圾回收时

跟踪对象的垃圾回收

垃圾回收后终止

上个图理解一下:

看图,当主线程结束,栈帧销毁,强引用ThreadLocal没有了。再看一下红色部分,

如果是强引用, 线程的ThreadLocalMap里某个entry的 k 引用还指向这个ThreadLocal对象,这样会导致k指向的ThreadLocal对象以及 v 指向的对象都不能被jvm虚拟机gc回收,造成内存泄漏。

如果是弱引用,就可以是ThreadLocal对象在执行完毕的时候被回收了,因为此时只有entry的k弱引用指向它,ThreadLocal回收后,k就指向为null了,但是v还是有值,也会有内存泄漏的风险,并不能保证不会内存泄漏。

那ThreadLocal为什么要使用弱引用而不是强引用呢?

总结 就是是减少严重内存泄漏的风险。

  1. 上面提到,key为弱引用,key为null时,value不为null,导致value无法被回收,引发内存泄漏。
  2. 弱引用尚且有内存泄漏的风险,强引用更加。使用线程池的时候,自定义的线程数不规范,若使用强引用,内存泄漏的风险更高。

如何防止内存泄漏?

上面提到entry的value还会有内存泄漏的风险。

ThreadLocal有通过方法:调用get,set或remove方法时,就会尝试删除key为null的entry,可以释放value对象所占用的内存。

上面demo的正确例子应该是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
new Thread(new Runnable() {
    @Override
    public void run() {
        try{
            threadLocal.set(1);
            System.out.println(threadLocal.get());
        }finally {
            threadLocal.remove(); //用完要remove,防止内存泄漏
        }
    }
}, "Thread1").start();

remove方法核心:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 private void remove(ThreadLocal<?> key) {
            Entry[] tab = table;
            int len = tab.length;
            int i = key.threadLocalHashCode & (len-1);
            for (Entry e = tab[i];
                 e != null;
                 e = tab[i = nextIndex(i, len)]) {
                if (e.get() == key) {
                    e.clear();
                    expungeStaleEntry(i); //调用消除方法
                    return;
                }
            }
        }
        
private int expungeStaleEntry(int staleSlot) {
    Entry[] tab = table;
    int len = tab.length;

    // expunge entry at staleSlot
    tab[staleSlot].value = null;   //把vaule赋值null
    tab[staleSlot] = null; 
    size--;

还有set方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// If key not found, put new entry in stale slot
tab[staleSlot].value = null;
tab[staleSlot] = new Entry(key, value);

参考:

https://blog.csdn.net/qq_33404395/article/details/82356344

https://www.cnblogs.com/shen-qian/p/12108655.html## 什么是ThreadLocal变量

ThreadLocal称为线程本地变量,其为变量在每个线程中都创建了一个副本,每个线程都访问和修改本线程中变量的副本,但每个线程之间的变量是不能相互访问的,ThreadLocal不是一个Thread。

ThreadLocal 有四个方法:

ThreadLocal作用

  1. ThreadLocal可以让线程独占资源,存储于线程内部,避免线程堵塞造成CPU吞吐下降。
  2. 使用同一个threadLocal ,但每个线程的变量是独立都,对其他线程不可见,不需要每个线程都 new 一个对象,减少了内存的开销。

ThreadLocal方法详解

demo:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ThreadLocalTest {

    public static void main(String[] args) {

        ThreadLocal<Integer> threadLocal = new ThreadLocal<>();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    threadLocal.set(1);
                    System.out.println(threadLocal.get());
                }finally {
                    threadLocal.remove();
                }
            }
        }, "Thread1").start();


        new Thread(new Runnable() {
            @Override
            public void run() {
                threadLocal.set(2);
                System.out.println(threadLocal.get());
            }
        }, "Thread2").start();


        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(threadLocal.get());
            }
        }, "Thread3").start();
    }

}

输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1
2
null

可以看到,每个线程使用都是对同一个threadLocal的引用,但是线程之间的变量是不能互相访问的。

ThreadLocal如何创建副本的?(如何维护变量的)

在每个Thread中包含一个ThreadLocalMap,ThreadLocalMap的key是ThreadLocal的对象,value是独享数据。

每个Thread 维护一个 ThreadLocalMap 映射表,这个映射表的 key 是 ThreadLocal实例本身,value 是真正需要存储的 Object。

也就是说 ThreadLocal 本身并不存储值,它只是作为一个 key 来让线程从 ThreadLocalMap 获取 value。

ThreadLocal内存泄漏问题

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static class Entry extends WeakReference<ThreadLocal<?>> {
    /** The value associated with this ThreadLocal. */
    Object value;

    Entry(ThreadLocal<?> k, Object v) {
        super(k); //继续深扒,key 是一个弱引用,以一个弱引用指向ThreadLcoal对象k
        value = v;
    }
}

ThreadLocalMap 是使用 ThreadLocal 的弱引用作为 Key 的,弱引用的对象在 GC 时会被回收。

ThreadLocalMap使用ThreadLocal的弱引用作为key,如果一个ThreadLocal没有外部强引用来引用它,那么系统 GC 的时候,这个ThreadLocal势必会被回收(为什么会被回收下面讲到),然后ThreadLocalMap中就会出现key为null的Entry,就没有办法访问这些key为null的Entry的value,如果当前线程再迟迟不结束的话,这些key为null的Entry的value就会一直存在一条强引用链:Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value 永远无法回收,造成内存泄漏。

以上总结就是,key为null被回收了,但是value还在,需要在set、get的时候判断才能回收。

那为什么value不能被设置成弱引用呢?

如果vaule设计为弱引用,你可能获取到的是null ,毫无意义。

为什么要使用弱引用而不是强引用?

强引用:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Object object= new Object();

强引用用的最多,无论任何情况下,只要强引用关系还存在,垃圾收集器就永远不会回收掉被引用的对象。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
object =null

对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显式地将相应(强)引用赋值为null,才可以当做垃圾被收集,当然具体回收时机还是要看垃圾收集策略。

而强引用是造成Java内存泄漏的主要原因之一,内存空间不足时,Java虚拟机会抛出OutOfMemoryError ,使程序异常终止,但是注意,抛出错误也不会回收这些强引用的对象。

弱引用:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
String str = new String("123");
WeakReference<String> weakReference = new WeakReference<>(str);
str = null;

在垃圾回收的一个周期内,jvm发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。

所以,弱引用相对强引用来说,生命周期更短。

参考四种引用:https://www.cnblogs.com/yanl55555/p/13365397.html

引用类型

被垃圾回收时间

用途

生存时间

强引用

从来不会

对象的一般状态

JVM停止运行时终止

软引用

当内存不足时

对象缓存

内存不足时终止

弱引用

正常垃圾回收时

对象缓存

垃圾回收后终止

虚引用

正常垃圾回收时

跟踪对象的垃圾回收

垃圾回收后终止

上个图理解一下:

看图,当主线程结束,栈帧销毁,强引用ThreadLocal没有了。再看一下红色部分,

如果是强引用, 线程的ThreadLocalMap里某个entry的 k 引用还指向这个ThreadLocal对象,这样会导致k指向的ThreadLocal对象以及 v 指向的对象都不能被jvm虚拟机gc回收,造成内存泄漏。

如果是弱引用,就可以是ThreadLocal对象在执行完毕的时候被回收了,因为此时只有entry的k弱引用指向它,ThreadLocal回收后,k就指向为null了,但是v还是有值,也会有内存泄漏的风险,并不能保证不会内存泄漏。

那ThreadLocal为什么要使用弱引用而不是强引用呢?

总结 就是是减少严重内存泄漏的风险。

  1. 上面提到,key为弱引用,key为null时,value不为null,导致value无法被回收,引发内存泄漏。
  2. 弱引用尚且有内存泄漏的风险,强引用更加。使用线程池的时候,自定义的线程数不规范,若使用强引用,内存泄漏的风险更高。

如何防止内存泄漏?

上面提到entry的value还会有内存泄漏的风险。

ThreadLocal有通过方法:调用get,set或remove方法时,就会尝试删除key为null的entry,可以释放value对象所占用的内存。

上面demo的正确例子应该是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
new Thread(new Runnable() {
    @Override
    public void run() {
        try{
            threadLocal.set(1);
            System.out.println(threadLocal.get());
        }finally {
            threadLocal.remove(); //用完要remove,防止内存泄漏
        }
    }
}, "Thread1").start();

remove方法核心:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 private void remove(ThreadLocal<?> key) {
            Entry[] tab = table;
            int len = tab.length;
            int i = key.threadLocalHashCode & (len-1);
            for (Entry e = tab[i];
                 e != null;
                 e = tab[i = nextIndex(i, len)]) {
                if (e.get() == key) {
                    e.clear();
                    expungeStaleEntry(i); //调用消除方法
                    return;
                }
            }
        }
        
private int expungeStaleEntry(int staleSlot) {
    Entry[] tab = table;
    int len = tab.length;

    // expunge entry at staleSlot
    tab[staleSlot].value = null;   //把vaule赋值null
    tab[staleSlot] = null; 
    size--;

还有set方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// If key not found, put new entry in stale slot
tab[staleSlot].value = null;
tab[staleSlot] = new Entry(key, value);

参考:

https://blog.csdn.net/qq_33404395/article/details/82356344

https://www.cnblogs.com/shen-qian/p/12108655.html

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/07/30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
进阶数据库系列(二十三):PostgreSQL 性能优化
PostgreSQL数据库优化是多方面的,原则是减少系统的瓶颈,减少资源的占用,增加系统的反应速度。例如:
民工哥
2023/08/22
4.2K0
进阶数据库系列(二十三):PostgreSQL 性能优化
PostgreSQL数据库导入大量数据时如何优化
来源 | OSCHINA 社区、作者 | PostgreSQLChina 链接:https://my.oschina.net/postgresqlchina/blog/5568852 在使用 PostgreSQL 的时候,我们某些时候会往库里插入大量数据,例如,导入测试数据,导入业务数据等等。本篇文章介绍了在导入大量数据时的一些可供选择的优化手段。可以结合自己的情况进行选择。 一、关闭自动提交 关闭自动提交,并且只在每次 (数据拷贝) 结束的时候做一次提交。 如果允许每个插入都独立地提交,那么 Postg
程序猿DD
2022/08/29
1.9K0
PostgreSQL技术大讲堂 - 第32讲:数据库参数调整
PostgreSQL从小白到专家,是从入门逐渐能力提升的一个系列教程,内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容,希望对热爱PG、学习PG的同学们有帮助,欢迎持续关注CUUG PG技术大讲堂。
用户5892232
2023/11/03
4650
PostgreSQL技术大讲堂 - 第32讲:数据库参数调整
从零开始学PostgreSQL (二): 配置文件
PostgreSQL 使用三个主要的配置文件来控制服务器的行为、网络访问和用户映射。下面是对这三个文件的详细介绍:
DBA实战
2024/09/06
7760
从零开始学PostgreSQL (二): 配置文件
数据库PostrageSQL-WAL配置
有几个WAL相关的配置参数会影响数据库性能。本节将解释它们的使用。关于服务器配置参数的设置的一般信息请参考Chapter 19。
cwl_java
2021/01/13
5870
从Oracle到PostgreSQL:一文掌握Checkpoint重要概念
墨墨导读:Checkpoint是数据库中重要的概念,无论在Oracle,MySQL这个概念,它主要功能是在检查点时刻,脏数据全部刷新到磁盘,以实现数据的一致性和完整性。PostgreSQL为什么要设计Checkpoint呢?跟Oracle一样,其主要目的是缩短崩溃恢复时间。PostgreSQL在崩溃恢复时会以最近的Checkpoint为基础,不断应用这之后的WAL日志。下面我们就从Oracle的角度去学习下PostgreSQL的Checkpoint。
数据和云
2019/07/30
1K0
pg 13批量插入最佳实践
背景:最近需要以编程方式将一千万条经纬数据记录插入到postgres数据库,最后通过一系列的实验验证,摸索出一些实践经验。
DB之路
2021/03/04
1.3K0
PostgreSQL集群篇——PostgreSQL的配置文件解析
日常中我们进行安装PostgreSQL后都需要对其进行配置基础配置,以便其能有效发挥出服务器的性能,下面是我进行整理后的postgresql.conf配置文件的相关注释,方便大家对于各个属性进行熟悉。
cn華少
2021/07/27
4K0
PostgreSQL 如何面对高压力下的写操作的优化
数据库的重要性能指标中有一项对于高并发下的数据库写操作,不少数据库都对此有执念,一秒钟写入的数据量是多少,并为此而自豪. 数据的写入在单位时间中的确是很重要的. POSTGRESQL 怎么能应对高并发下的写操作,并且在不改变目前的硬件的条件的基础上, 怎么进行优化.
postgres
2023/07/12
3430
--POSTGRESQL FULL PAGE 优化 与 CHECKPOINT 的“矛盾”!
在说完mysql 不要关DW 后,祭出 POSTGRESQL FULL PAGE 的确是有点不厚道,所以必然会引出 FULL PAGE 也存在性能问题的话题。到底是大公鸡和大马猴的问题,还是小绵羊的牧羊犬的故事。
AustinDatabases
2020/03/31
9460
PostgreSQL统计信息的几个重要视图
比如tup_returned值明显大于tup_fetched,历史SQL语句很多是全表扫描,存在没有使用索引的SQL,可结合pg_stat_statments查找慢SQL,也可结合pg_stat_user_table找全表扫描次数和行数最多的表;
yzsDBA
2020/10/29
1.3K0
PostgreSql 学了还是乱麻,那就捋一捋 DB架构
其实学习的过程中,很容易陷入一个问题,貌似都懂,一问就含糊,今天就自己捋一捋的那团乱麻。
AustinDatabases
2020/05/09
5400
PostgreSQL备份恢复实现
本文主要介绍pg_dump、pg_dumpall、copy、pg_basebackup的使用。
数据和云
2021/09/22
5.8K0
PostgreSQL备份恢复实现
POSTGRESQL MYSQL MONGODB 配置文件总结(感谢我的三个DBA)
最近在整理POSTGRESQL MYSQL MONGODB REDIS 的标准化模板配置参数,当然这里面还包含 LINUX 的一些基本配置. 相关的整理的工作是我的三个 DBA 操作的, 针对目前的参数进行了相关的整理和重新设定. 昨天有人问我要,这边进贴出来,如果大家有什么问题 ,告诉我们, 大家一起进步.
AustinDatabases
2021/02/26
8630
从零开始学PostgreSQL (六): 备份和恢复
PostgreSQL 提供了多种备份和恢复策略,旨在满足不同规模和需求的数据库环境。以下是 PostgreSQL 备份和恢复的主要方法概览:
DBA实战
2024/09/06
9650
从零开始学PostgreSQL (六): 备份和恢复
PostgreSQL 性能优化全方位指南:深度提升数据库效率
在现代互联网应用中,数据库性能优化是系统优化中至关重要的一环,尤其对于数据密集型和高并发的应用而言,PostgreSQL(以下简称PG)凭借其丰富的特性和强大的功能,成为很多企业的首选。然而,随着数据规模的扩展和查询复杂度的提升,PostgreSQL的性能问题逐渐显现。本文将详细介绍PostgreSQL性能优化的各个方面,涵盖硬件调优、数据库配置、索引使用、查询优化等内容,帮助你全方位提升数据库的效率。
用户11404404
2024/12/13
9060
PostgreSQL中的预写式日志
预写式日志write ahead log,是数据库保证数据完整性的重要数据结构。数据库管理器将数据库发生的变更记录写入wal日志缓冲区,进而写入wal日志文件中,在数据库崩溃时利用wal日志进行重演恢复,这几乎是所有数据库的统一实现原理。
数据库架构之美
2020/07/28
1.3K0
从零开始学PostgreSQL (八):监控数据库动态
PostgreSQL 提供了一套丰富的统计信息收集和报告机制,用于监控数据库的运行状况和性能。以下是这些机制的一些关键要点:
DBA实战
2024/09/06
2120
从零开始学PostgreSQL (八):监控数据库动态
数据库PostrageSQL-服务器配置资源消耗
shared_buffers (integer) 设置数据库服务器将使用的共享内存缓冲区量。默认通常是 128 兆字节(128MB),但是如果你的内核设置不支持(在initdb时决定),那么可以会更少。这个设置必须至少为 128 千字节(BLCKSZ的非默认值将改变最小值)。不过为了更好的性能,通常会使用明显高于最小值的设置。
cwl_java
2020/10/15
1.6K0
数据库PostrageSQL-连续归档和时间点恢复(PITR)
在任何时间,PostgreSQL在数据集簇目录的pg_wal/子目录下都保持有一个预写式日志(WAL)。这个日志存在的目的是为了保证崩溃后的安全:如果系统崩溃,可以“重放”从最后一次检查点以来的日志项来恢复数据库的一致性。该日志的存在也使得第三种备份数据库的策略变得可能:我们可以把一个文件系统级别的备份和WAL文件的备份结合起来。当需要恢复时,我们先恢复文件系统备份,然后从备份的WAL文件中重放来把系统带到一个当前状态。这种方法比之前的方法管理起来要更复杂,但是有其显著的优点:
cwl_java
2020/12/22
1.1K0
推荐阅读
相关推荐
进阶数据库系列(二十三):PostgreSQL 性能优化
更多 >
目录
  • 什么是ThreadLocal变量
  • ThreadLocal作用
  • ThreadLocal方法详解
  • ThreadLocal如何创建副本的?(如何维护变量的)
  • ThreadLocal内存泄漏问题
  • 为什么要使用弱引用而不是强引用?
    • 强引用:
    • 弱引用:
  • 如何防止内存泄漏?
  • ThreadLocal作用
  • ThreadLocal方法详解
  • ThreadLocal如何创建副本的?(如何维护变量的)
  • ThreadLocal内存泄漏问题
  • 为什么要使用弱引用而不是强引用?
    • 强引用:
    • 弱引用:
  • 如何防止内存泄漏?
  • ThreadLocal作用
  • ThreadLocal方法详解
  • ThreadLocal如何创建副本的?(如何维护变量的)
  • ThreadLocal内存泄漏问题
  • 为什么要使用弱引用而不是强引用?
    • 强引用:
    • 弱引用:
  • 如何防止内存泄漏?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档