Rumah  >  Artikel  >  Java  >  Apakah sebab mengapa ThreadLocal di Java menyebabkan limpahan memori (Out Of Memory)?

Apakah sebab mengapa ThreadLocal di Java menyebabkan limpahan memori (Out Of Memory)?

WBOY
WBOYke hadapan
2023-04-23 23:58:091081semak imbas

Analisis Punca

Apakah sebab ThreadLocal menyebabkan memori OOM?

Lapisan asas ThreadLocal menyimpan data melalui ThreadLocalMap

Kod sumber adalah seperti berikut:

Apakah sebab mengapa ThreadLocal di Java menyebabkan limpahan memori (Out Of Memory)?

  • Apabila kami menggunakan ThreadLocal.set(), nilai dan kunci set (iaitu kelas ThreadLocal yang ditakrifkan oleh perniagaan) akan disimpan dalam tatasusunan Entry[] ThreadLocalMap

Kod sumber adalah seperti berikut:

Apakah sebab mengapa ThreadLocal di Java menyebabkan limpahan memori (Out Of Memory)?

  • Antaranya, Entry mengimplementasikan lemah rujukan WeakReference, dan kunci Entri (iaitu, kelas ThreadLocal yang ditakrifkan oleh pihak perniagaan) akan Ia dibalut menjadi rujukan yang lemah dan digunakan sebagai kunci Kemasukan. Takrifan rujukan lemah Java ialah apabila JVM melakukan imbasan kutipan sampah dan menemui objek dengan rujukan yang lemah sahaja, ia akan segera mengitar semula objek Ini adalah cara untuk menghalang limpahan memori apabila ThreadLocal pada asalnya direka

Kod sumber adalah seperti berikut:

Apakah sebab mengapa ThreadLocal di Java menyebabkan limpahan memori (Out Of Memory)?

Walaupun kuncinya dimasukkan ke dalam rujukan yang lemah dan akan dikitar semula oleh mekanisme pengumpulan sampah, nilai Mungkin ada rantai rujukan yang kuat apabila benang (Benang) tidak mati

Memandangkan

adalah rujukan yang kuat, selagi value tidak mati, seperti. kumpulan benang, rantai rujukan yang kukuh ini akan wujud , kemudian Thread tidak akan dikitar semula, yang boleh menyebabkan limpahan memori value

Hubungan rujukan adalah seperti berikut: Benang ==> ThreadLocalMap ==> Entri ==> nilai

Tetapi tindakan menghapuskan rantaian rujukan yang kuat ini perlu dicetuskan oleh pihak perniagaan dalam kes mendapatkan , atau mungkin kunci get tidak kosong, dan kelas expungeStaleEntry tidak akan dicetuskan. Oleh itu, pembangun harus membangunkan tabiat yang baik dan ingat untuk melaraskan kaedah

sekali selepas menggunakan ThreadLocal atau cara penggunaan yang betul ThreadLocal.remove()ThreadLocal.set(null)

public class ThreadLocalTest {
    /**
     * 未初始化的本地线程变量
     */
    private static ThreadLocal<User> userThreadLocal = new ThreadLocal<>();
    public static void main(String[] args) throws InterruptedException {
        int threadNum = 10;
        List<Thread> threadList = Lists.newArrayList();

        for (int i = 0; i < threadNum; ++i) {
            long userId = i;
            Thread t = new Thread(() -> {
                try {
                    // 设置变量值
                    userThreadLocal.set(new User(userId, "lanxing" + userId, "2x"));
                    // 使用变量
                    doSomething();
                } finally {
                    // 移除变量
                    userThreadLocal.remove();   //移除ThreadLocal变量
                }
            }, "T" + i);
            threadList.add(t);
            t.start();
        }

        for (int i = 0; i < threadNum; ++i) {
            threadList.get(i).join();
        }
    }
    private static void doSomething() {
        log.info("Use ThreadLocal variable :{}", JSON.toJSONString(userThreadLocal.get()));
    }
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class User {
    private Long id;
    private String name;
    private String level;
}

Cetak hasil:

14:30:26.790 [T2] INFO io.zhengsh.order.tool.ThreadLocalTest - Gunakan pembolehubah ThreadLocal :{"id":2,"level":" 2x ","name":"lanxing2"}

14:30:26.789 [T5] INFO io.zhengsh.order.tool.ThreadLocalTest - Gunakan pembolehubah ThreadLocal :{"id":5,"level":"2x " ,"name":"lanxing5"}
14:30:26.792 [T0] INFO io.zhengsh.order.tool.ThreadLocalTest - Gunakan pembolehubah ThreadLocal :{"id":0,"level":"2x" , "name":"lanxing0"}
14:30:26.792 [T4] INFO io.zhengsh.order.tool.ThreadLocalTest - Gunakan pembolehubah ThreadLocal :{"id":4,"level":"2x", " name":"lanxing4"}
14:30:26.792 [T8] INFO io.zhengsh.order.tool.ThreadLocalTest - Gunakan pembolehubah ThreadLocal :{"id":8,"level":"2x"," name ":"lanxing8"}
14:30:26.791 [T1] INFO io.zhengsh.order.tool.ThreadLocalTest - Gunakan pembolehubah ThreadLocal :{"id":1,"level":"2x","name " :"lanxing1"}
14:30:26.792 [T7] INFO io.zhengsh.order.tool.ThreadLocalTest - Gunakan pembolehubah ThreadLocal :{"id":7,"level":"2x","name" : "lanxing7"}
14:30:26.792 [T6] INFO io.zhengsh.order.tool.ThreadLocalTest - Gunakan pembolehubah ThreadLocal :{"id":6,"level":"2x","name": " lanxing6"}
14:30:26.791 [T9] INFO io.zhengsh.order.tool.ThreadLocalTest - Gunakan pembolehubah ThreadLocal :{"id":9,"level":"2x","name":" lanxing9 "}
14:30:26.790 [T3] INFO io.zhengsh.order.tool.ThreadLocalTest - Gunakan pembolehubah ThreadLocal :{"id":3,"level":"2x","name":"lanxing3 " }

Atas ialah kandungan terperinci Apakah sebab mengapa ThreadLocal di Java menyebabkan limpahan memori (Out Of Memory)?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam